diff --git a/Cargo.lock b/Cargo.lock index 8a569c16..51a8fa49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -70,6 +76,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2" version = "0.8.1" @@ -84,11 +102,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -105,11 +123,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -134,9 +152,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byte-tools" @@ -152,15 +170,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.76" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -170,13 +188,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "time", "wasm-bindgen", @@ -185,25 +203,15 @@ dependencies = [ [[package]] name = "clipboard-win" -version = "4.4.2" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" dependencies = [ "error-code", "str-buf", "winapi", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -216,9 +224,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpu-time" @@ -232,9 +240,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] @@ -270,7 +278,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2db40892a506901e4e8281f00e42687df82d1d3448cb0289ae9183a60cb42ec1" dependencies = [ - "blake2 0.10.4", + "blake2 0.10.6", "rand_core", "sha2", ] @@ -281,7 +289,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "typenum", ] @@ -297,56 +305,12 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.3" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" dependencies = [ - "nix 0.25.0", - "winapi", -] - -[[package]] -name = "cxx" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "nix 0.26.2", + "windows-sys 0.48.0", ] [[package]] @@ -357,7 +321,7 @@ checksum = "dcdbcee2d9941369faba772587a565f4f534e42cb8d17e5295871de730163b2b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -377,13 +341,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -421,18 +385,18 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "signature", ] [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "endian-type" @@ -442,13 +406,13 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -473,22 +437,22 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "fd-lock" -version = "3.0.8" +version = "3.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27" +checksum = "39ae6b3d9530211fb3b12a95374b8b0823be812f53d09e18c5675c0146b09642" dependencies = [ "cfg-if", "rustix", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -512,6 +476,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futf" version = "0.1.5" @@ -524,9 +494,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -539,9 +509,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -549,15 +519,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -566,38 +536,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -631,9 +601,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -641,9 +611,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -669,24 +639,24 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "gmp-mpfr-sys" -version = "1.4.10" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3f42dadb6c75f122e9aa87e757ef11d4282f664c9f2e6476a9c2c8970f9d19" +checksum = "13eabc29d16e4a621b495e3919c71ebb7caaed24380955671e7d417370fea95d" dependencies = [ "libc", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "h2" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -718,13 +688,19 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hostname" version = "0.3.1" @@ -747,14 +723,14 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -786,9 +762,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", @@ -823,33 +799,32 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -866,12 +841,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.1" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi 0.3.1", "libc", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -885,24 +861,27 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] [[package]] name = "lazy_static" @@ -935,15 +914,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libffi" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb06d5b4c428f3cd682943741c39ed4157ae989fffe1094a08eaf7c4014cf60" +checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" dependencies = [ "libc", "libffi-sys", @@ -951,9 +930,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c6f11e063a27ffe040a9d15f0b661bf41edc2383b7ae0e0ad5a7e7d53d9da3" +checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c" dependencies = [ "cc", ] @@ -980,26 +959,17 @@ dependencies = [ "walkdir", ] -[[package]] -name = "link-cplusplus" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] - [[package]] name = "linux-raw-sys" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb68f22743a3fb35785f1e7f844ca5a3de2dde5bd0c0ef5b372065814699b121" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -1007,12 +977,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "mac" @@ -1082,14 +1049,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -1117,7 +1083,7 @@ source = "git+https://github.com/mthom/modular-bitfield#213535c684af277563678179 dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1155,9 +1121,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" dependencies = [ "bitflags", "cc", @@ -1168,14 +1134,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "autocfg", "bitflags", "cfg-if", "libc", + "static_assertions", ] [[package]] @@ -1187,16 +1153,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1208,19 +1164,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1245,13 +1201,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -1289,7 +1245,7 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.5", + "parking_lot_core 0.8.6", ] [[package]] @@ -1299,34 +1255,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.4", + "parking_lot_core 0.9.8", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", - "windows-sys 0.42.0", + "windows-targets", ] [[package]] @@ -1390,7 +1346,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1425,9 +1381,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "ppv-lite86" @@ -1443,9 +1399,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "predicates" -version = "2.1.2" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab68289ded120dcbf9d571afcf70163233229052aec9b08ab09532f698d0e1e6" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "itertools", @@ -1454,15 +1410,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e7125585d872860e9955ca571650b27a4979c5823084168c5ed5bbfb016b56" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" [[package]] name = "predicates-tree" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad3f7fa8d61e139cbc7c3edfebf3b6678883a53f5ffac65d1259329a93ee43a5" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" dependencies = [ "predicates-core", "termtree", @@ -1470,28 +1426,34 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "radix_trie" version = "0.2.1" @@ -1541,6 +1503,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -1548,7 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -1564,15 +1535,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "ring" version = "0.16.20" @@ -1610,9 +1572,9 @@ dependencies = [ [[package]] name = "rug" -version = "1.17.0" +version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203180f444c95eac53586ed04793ecf6454c5d28f9eca8eead815fc19e136c47" +checksum = "555e8b44763d034526db899c88cd56ccc4486cd38b444c8aa0e79d4e70ae5a34" dependencies = [ "az", "gmp-mpfr-sys", @@ -1621,23 +1583,23 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.1" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812a2ec2043c4d6bc6482f5be2ab8244613cac2493d128d36c0759e52a626ab3" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rustyline" @@ -1653,7 +1615,7 @@ dependencies = [ "libc", "log", "memchr", - "nix 0.23.1", + "nix 0.23.2", "radix_trie", "scopeguard", "smallvec", @@ -1665,9 +1627,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "same-file" @@ -1680,12 +1642,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -1694,18 +1655,14 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - [[package]] name = "scryer-prolog" version = "0.9.1" dependencies = [ "assert_cmd", "base64", + "bit-set", + "bitvec", "blake2 0.8.1", "chrono", "cpu-time", @@ -1749,7 +1706,7 @@ dependencies = [ "static_assertions", "strum", "strum_macros", - "syn", + "syn 1.0.109", "to-syn-value", "to-syn-value_derive", "tokio", @@ -1758,9 +1715,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ "bitflags", "core-foundation", @@ -1771,9 +1728,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -1792,9 +1749,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" [[package]] name = "serial_test" @@ -1815,18 +1772,18 @@ checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.7", ] [[package]] @@ -1844,9 +1801,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -1865,9 +1822,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -1886,9 +1843,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -1901,9 +1858,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -1981,7 +1938,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", ] [[package]] @@ -1992,15 +1949,15 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -2008,17 +1965,34 @@ dependencies = [ ] [[package]] -name = "tempfile" -version = "3.3.0" +name = "syn" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +dependencies = [ + "autocfg", "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.48.0", ] [[package]] @@ -2032,46 +2006,37 @@ dependencies = [ "utf-8", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "termtree" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -2084,7 +2049,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45dcb7b4108a4793bdd74aa3714296c6eaf43663edf73fa8625d0d7621e68447" dependencies = [ - "syn", + "syn 1.0.109", "to-syn-value_derive", ] @@ -2096,45 +2061,44 @@ checksum = "cd4fdec6de01b568c1d3721c9d46a352623c536cd55a8a5acfefb63d1fccccbc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "tokio" -version = "1.24.2" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "bytes", "libc", - "memchr", - "mio 0.8.5", + "mio 0.8.8", "num_cpus", "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -2142,9 +2106,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -2173,36 +2137,36 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" @@ -2224,9 +2188,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "vcpkg" @@ -2251,22 +2215,20 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -2284,9 +2246,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2294,24 +2256,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.18", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2319,28 +2281,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2378,16 +2340,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets", ] [[package]] @@ -2396,86 +2354,131 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] [[package]] name = "xml5ever" diff --git a/Cargo.toml b/Cargo.toml index df90f142..99218c71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,8 @@ to-syn-value_derive = "0.1.0" walkdir = "2" [dependencies] +bit-set = "0.5.3" +bitvec = "1" cpu-time = "1.0.0" crossterm = "0.20.0" dirs-next = "2.0.0" diff --git a/build/instructions_template.rs b/build/instructions_template.rs index 1fd2a60a..8e61ad23 100644 --- a/build/instructions_template.rs +++ b/build/instructions_template.rs @@ -639,8 +639,10 @@ enum InstructionTemplate { Cut(RegType), #[strum_discriminants(strum(props(Arity = "1", Name = "get_level")))] GetLevel(RegType), - #[strum_discriminants(strum(props(Arity = "1", Name = "get_level_and_unify")))] - GetLevelAndUnify(RegType), + #[strum_discriminants(strum(props(Arity = "1", Name = "get_prev_level")))] + GetPrevLevel(RegType), + #[strum_discriminants(strum(props(Arity = "1", Name = "get_cut_point")))] + GetCutPoint(RegType), #[strum_discriminants(strum(props(Arity = "0", Name = "neck_cut")))] NeckCut, // choice instruction @@ -742,10 +744,8 @@ enum InstructionTemplate { Allocate(usize), // num_frames. #[strum_discriminants(strum(props(Arity = "0", Name = "deallocate")))] Deallocate, - #[strum_discriminants(strum(props(Arity = "arity", Name = "jmp_by_call")))] - JmpByCall(usize, usize), // arity, relative offset. - #[strum_discriminants(strum(props(Arity = "arity", Name = "jmp_by_execute")))] - JmpByExecute(usize, usize), // arity, relative offset. + #[strum_discriminants(strum(props(Arity = "1", Name = "jmp_by_call")))] + JmpByCall(usize), // relative offset. #[strum_discriminants(strum(props(Arity = "1", Name = "rev_jmp_by")))] RevJmpBy(usize), #[strum_discriminants(strum(props(Arity = "0", Name = "proceed")))] @@ -1116,6 +1116,7 @@ fn generate_instruction_preface() -> TokenStream { } pub type Code = Vec; + pub type CodeDeque = VecDeque; impl Instruction { #[inline] @@ -1298,9 +1299,13 @@ fn generate_instruction_preface() -> TokenStream { let rt_stub = reg_type_into_functor(r); functor!(atom!("get_level"), [str(h, 0)], [rt_stub]) } - &Instruction::GetLevelAndUnify(r) => { + &Instruction::GetPrevLevel(r) => { let rt_stub = reg_type_into_functor(r); - functor!(atom!("get_level_and_unify"), [str(h, 0)], [rt_stub]) + functor!(atom!("get_prev_level"), [str(h, 0)], [rt_stub]) + } + &Instruction::GetCutPoint(r) => { + let rt_stub = reg_type_into_functor(r); + functor!(atom!("get_cut_point"), [str(h, 0)], [rt_stub]) } &Instruction::NeckCut => { functor!(atom!("neck_cut")) @@ -1455,30 +1460,30 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::DefaultExecuteNamed(arity, name, ..) => { functor!(atom!("execute_default"), [atom(name), fixnum(arity)]) } - &Instruction::CallN(arity, _) => { + &Instruction::CallN(arity) => { functor!(atom!("call_n"), [fixnum(arity)]) } - &Instruction::ExecuteN(arity, _) => { + &Instruction::ExecuteN(arity) => { functor!(atom!("execute_n"), [fixnum(arity)]) } - &Instruction::DefaultCallN(arity, _) => { + &Instruction::DefaultCallN(arity) => { functor!(atom!("call_default_n"), [fixnum(arity)]) } - &Instruction::DefaultExecuteN(arity, _) => { + &Instruction::DefaultExecuteN(arity) => { functor!(atom!("execute_default_n"), [fixnum(arity)]) } - &Instruction::CallFastCallN(arity, _) => { + &Instruction::CallFastCallN(arity) => { functor!(atom!("call_fast_call_n"), [fixnum(arity)]) } - &Instruction::ExecuteFastCallN(arity, _) => { + &Instruction::ExecuteFastCallN(arity) => { functor!(atom!("execute_fast_call_n"), [fixnum(arity)]) } - &Instruction::CallTermGreaterThan(_) | - &Instruction::CallTermLessThan(_) | - &Instruction::CallTermGreaterThanOrEqual(_) | - &Instruction::CallTermLessThanOrEqual(_) | - &Instruction::CallTermEqual(_) | - &Instruction::CallTermNotEqual(_) | + &Instruction::CallTermGreaterThan | + &Instruction::CallTermLessThan | + &Instruction::CallTermGreaterThanOrEqual | + &Instruction::CallTermLessThanOrEqual | + &Instruction::CallTermEqual | + &Instruction::CallTermNotEqual | &Instruction::CallNumberGreaterThan(..) | &Instruction::CallNumberLessThan(..) | &Instruction::CallNumberGreaterThanOrEqual(..) | @@ -1486,561 +1491,561 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::CallNumberEqual(..) | &Instruction::CallNumberNotEqual(..) | &Instruction::CallIs(..) | - &Instruction::CallAcyclicTerm(_) | - &Instruction::CallArg(_) | - &Instruction::CallCompare(_) | - &Instruction::CallCopyTerm(_) | - &Instruction::CallFunctor(_) | - &Instruction::CallGround(_) | - &Instruction::CallKeySort(_) | - &Instruction::CallRead(_) | - &Instruction::CallSort(_) => { + &Instruction::CallAcyclicTerm | + &Instruction::CallArg | + &Instruction::CallCompare | + &Instruction::CallCopyTerm | + &Instruction::CallFunctor | + &Instruction::CallGround | + &Instruction::CallKeySort | + &Instruction::CallRead | + &Instruction::CallSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call"), [atom(name), fixnum(arity)]) } // - &Instruction::ExecuteTermGreaterThan(_) | - &Instruction::ExecuteTermLessThan(_) | - &Instruction::ExecuteTermGreaterThanOrEqual(_) | - &Instruction::ExecuteTermLessThanOrEqual(_) | - &Instruction::ExecuteTermEqual(_) | - &Instruction::ExecuteTermNotEqual(_) | + &Instruction::ExecuteTermGreaterThan | + &Instruction::ExecuteTermLessThan | + &Instruction::ExecuteTermGreaterThanOrEqual | + &Instruction::ExecuteTermLessThanOrEqual | + &Instruction::ExecuteTermEqual | + &Instruction::ExecuteTermNotEqual | &Instruction::ExecuteNumberGreaterThan(..) | &Instruction::ExecuteNumberLessThan(..) | &Instruction::ExecuteNumberGreaterThanOrEqual(..) | &Instruction::ExecuteNumberLessThanOrEqual(..) | &Instruction::ExecuteNumberEqual(..) | &Instruction::ExecuteNumberNotEqual(..) | - &Instruction::ExecuteAcyclicTerm(_) | - &Instruction::ExecuteArg(_) | - &Instruction::ExecuteCompare(_) | - &Instruction::ExecuteCopyTerm(_) | - &Instruction::ExecuteFunctor(_) | - &Instruction::ExecuteGround(_) | + &Instruction::ExecuteAcyclicTerm | + &Instruction::ExecuteArg | + &Instruction::ExecuteCompare | + &Instruction::ExecuteCopyTerm | + &Instruction::ExecuteFunctor | + &Instruction::ExecuteGround | &Instruction::ExecuteIs(..) | - &Instruction::ExecuteKeySort(_) | - &Instruction::ExecuteRead(_) | - &Instruction::ExecuteSort(_) => { + &Instruction::ExecuteKeySort | + &Instruction::ExecuteRead | + &Instruction::ExecuteSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute"), [atom(name), fixnum(arity)]) } // - &Instruction::DefaultCallTermGreaterThan(_) | - &Instruction::DefaultCallTermLessThan(_) | - &Instruction::DefaultCallTermGreaterThanOrEqual(_) | - &Instruction::DefaultCallTermLessThanOrEqual(_) | - &Instruction::DefaultCallTermEqual(_) | - &Instruction::DefaultCallTermNotEqual(_) | + &Instruction::DefaultCallTermGreaterThan | + &Instruction::DefaultCallTermLessThan | + &Instruction::DefaultCallTermGreaterThanOrEqual | + &Instruction::DefaultCallTermLessThanOrEqual | + &Instruction::DefaultCallTermEqual | + &Instruction::DefaultCallTermNotEqual | &Instruction::DefaultCallNumberGreaterThan(..) | &Instruction::DefaultCallNumberLessThan(..) | &Instruction::DefaultCallNumberGreaterThanOrEqual(..) | &Instruction::DefaultCallNumberLessThanOrEqual(..) | &Instruction::DefaultCallNumberEqual(..) | &Instruction::DefaultCallNumberNotEqual(..) | - &Instruction::DefaultCallAcyclicTerm(_) | - &Instruction::DefaultCallArg(_) | - &Instruction::DefaultCallCompare(_) | - &Instruction::DefaultCallCopyTerm(_) | - &Instruction::DefaultCallFunctor(_) | - &Instruction::DefaultCallGround(_) | + &Instruction::DefaultCallAcyclicTerm | + &Instruction::DefaultCallArg | + &Instruction::DefaultCallCompare | + &Instruction::DefaultCallCopyTerm | + &Instruction::DefaultCallFunctor | + &Instruction::DefaultCallGround | &Instruction::DefaultCallIs(..) | - &Instruction::DefaultCallKeySort(_) | - &Instruction::DefaultCallRead(_) | - &Instruction::DefaultCallSort(_) => { + &Instruction::DefaultCallKeySort | + &Instruction::DefaultCallRead | + &Instruction::DefaultCallSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call_default"), [atom(name), fixnum(arity)]) } // - &Instruction::DefaultExecuteTermGreaterThan(_) | - &Instruction::DefaultExecuteTermLessThan(_) | - &Instruction::DefaultExecuteTermGreaterThanOrEqual(_) | - &Instruction::DefaultExecuteTermLessThanOrEqual(_) | - &Instruction::DefaultExecuteTermEqual(_) | - &Instruction::DefaultExecuteTermNotEqual(_) | + &Instruction::DefaultExecuteTermGreaterThan | + &Instruction::DefaultExecuteTermLessThan | + &Instruction::DefaultExecuteTermGreaterThanOrEqual | + &Instruction::DefaultExecuteTermLessThanOrEqual | + &Instruction::DefaultExecuteTermEqual | + &Instruction::DefaultExecuteTermNotEqual | &Instruction::DefaultExecuteNumberGreaterThan(..) | &Instruction::DefaultExecuteNumberLessThan(..) | &Instruction::DefaultExecuteNumberGreaterThanOrEqual(..) | &Instruction::DefaultExecuteNumberLessThanOrEqual(..) | &Instruction::DefaultExecuteNumberEqual(..) | &Instruction::DefaultExecuteNumberNotEqual(..) | - &Instruction::DefaultExecuteAcyclicTerm(_) | - &Instruction::DefaultExecuteArg(_) | - &Instruction::DefaultExecuteCompare(_) | - &Instruction::DefaultExecuteCopyTerm(_) | - &Instruction::DefaultExecuteFunctor(_) | - &Instruction::DefaultExecuteGround(_) | + &Instruction::DefaultExecuteAcyclicTerm | + &Instruction::DefaultExecuteArg | + &Instruction::DefaultExecuteCompare | + &Instruction::DefaultExecuteCopyTerm | + &Instruction::DefaultExecuteFunctor | + &Instruction::DefaultExecuteGround | &Instruction::DefaultExecuteIs(..) | - &Instruction::DefaultExecuteKeySort(_) | - &Instruction::DefaultExecuteRead(_) | - &Instruction::DefaultExecuteSort(_) => { + &Instruction::DefaultExecuteKeySort | + &Instruction::DefaultExecuteRead | + &Instruction::DefaultExecuteSort => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute_default"), [atom(name), fixnum(arity)]) } - &Instruction::CallIsAtom(_, _) | - &Instruction::CallIsAtomic(_, _) | - &Instruction::CallIsCompound(_, _) | - &Instruction::CallIsInteger(_, _) | - &Instruction::CallIsNumber(_, _) | - &Instruction::CallIsRational(_, _) | - &Instruction::CallIsFloat(_, _) | - &Instruction::CallIsNonVar(_, _) | - &Instruction::CallIsVar(_, _) => { + &Instruction::CallIsAtom(_) | + &Instruction::CallIsAtomic(_) | + &Instruction::CallIsCompound(_) | + &Instruction::CallIsInteger(_) | + &Instruction::CallIsNumber(_) | + &Instruction::CallIsRational(_) | + &Instruction::CallIsFloat(_) | + &Instruction::CallIsNonVar(_) | + &Instruction::CallIsVar(_) => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call"), [atom(name), fixnum(arity)]) } - &Instruction::ExecuteIsAtom(_, _) | - &Instruction::ExecuteIsAtomic(_, _) | - &Instruction::ExecuteIsCompound(_, _) | - &Instruction::ExecuteIsInteger(_, _) | - &Instruction::ExecuteIsNumber(_, _) | - &Instruction::ExecuteIsRational(_, _) | - &Instruction::ExecuteIsFloat(_, _) | - &Instruction::ExecuteIsNonVar(_, _) | - &Instruction::ExecuteIsVar(_, _) => { + &Instruction::ExecuteIsAtom(_) | + &Instruction::ExecuteIsAtomic(_) | + &Instruction::ExecuteIsCompound(_) | + &Instruction::ExecuteIsInteger(_) | + &Instruction::ExecuteIsNumber(_) | + &Instruction::ExecuteIsRational(_) | + &Instruction::ExecuteIsFloat(_) | + &Instruction::ExecuteIsNonVar(_) | + &Instruction::ExecuteIsVar(_) => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute"), [atom(name), fixnum(arity)]) } // - &Instruction::CallAtomChars(_) | - &Instruction::CallAtomCodes(_) | - &Instruction::CallAtomLength(_) | - &Instruction::CallBindFromRegister(_) | - &Instruction::CallContinuation(_) | - &Instruction::CallCharCode(_) | - &Instruction::CallCharType(_) | - &Instruction::CallCharsToNumber(_) | - &Instruction::CallCodesToNumber(_) | - &Instruction::CallCopyTermWithoutAttrVars(_) | - &Instruction::CallCheckCutPoint(_) | - &Instruction::CallClose(_) | - &Instruction::CallCopyToLiftedHeap(_) | - &Instruction::CallCreatePartialString(_) | - &Instruction::CallCurrentHostname(_) | - &Instruction::CallCurrentInput(_) | - &Instruction::CallCurrentOutput(_) | - &Instruction::CallDirectoryFiles(_) | - &Instruction::CallFileSize(_) | - &Instruction::CallFileExists(_) | - &Instruction::CallDirectoryExists(_) | - &Instruction::CallDirectorySeparator(_) | - &Instruction::CallMakeDirectory(_) | - &Instruction::CallMakeDirectoryPath(_) | - &Instruction::CallDeleteFile(_) | - &Instruction::CallRenameFile(_) | - &Instruction::CallFileCopy(_) | - &Instruction::CallWorkingDirectory(_) | - &Instruction::CallDeleteDirectory(_) | - &Instruction::CallPathCanonical(_) | - &Instruction::CallFileTime(_) | + &Instruction::CallAtomChars | + &Instruction::CallAtomCodes | + &Instruction::CallAtomLength | + &Instruction::CallBindFromRegister | + &Instruction::CallContinuation | + &Instruction::CallCharCode | + &Instruction::CallCharType | + &Instruction::CallCharsToNumber | + &Instruction::CallCodesToNumber | + &Instruction::CallCopyTermWithoutAttrVars | + &Instruction::CallCheckCutPoint | + &Instruction::CallClose | + &Instruction::CallCopyToLiftedHeap | + &Instruction::CallCreatePartialString | + &Instruction::CallCurrentHostname | + &Instruction::CallCurrentInput | + &Instruction::CallCurrentOutput | + &Instruction::CallDirectoryFiles | + &Instruction::CallFileSize | + &Instruction::CallFileExists | + &Instruction::CallDirectoryExists | + &Instruction::CallDirectorySeparator | + &Instruction::CallMakeDirectory | + &Instruction::CallMakeDirectoryPath | + &Instruction::CallDeleteFile | + &Instruction::CallRenameFile | + &Instruction::CallFileCopy | + &Instruction::CallWorkingDirectory | + &Instruction::CallDeleteDirectory | + &Instruction::CallPathCanonical | + &Instruction::CallFileTime | &Instruction::CallDynamicModuleResolution(..) | &Instruction::CallPrepareCallClause(..) | - &Instruction::CallCompileInlineOrExpandedGoal(..) | - &Instruction::CallIsExpandedOrInlined(_) | - &Instruction::CallGetClauseP(_) | - &Instruction::CallInvokeClauseAtP(_) | - &Instruction::CallGetFromAttributedVarList(_) | - &Instruction::CallPutToAttributedVarList(_) | - &Instruction::CallDeleteFromAttributedVarList(_) | - &Instruction::CallDeleteAllAttributesFromVar(_) | - &Instruction::CallUnattributedVar(_) | - &Instruction::CallGetDBRefs(_) | - &Instruction::CallFetchGlobalVar(_) | - &Instruction::CallFirstStream(_) | - &Instruction::CallFlushOutput(_) | - &Instruction::CallGetByte(_) | - &Instruction::CallGetChar(_) | - &Instruction::CallGetNChars(_) | - &Instruction::CallGetCode(_) | - &Instruction::CallGetSingleChar(_) | - &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff(_) | - &Instruction::CallTruncateIfNoLiftedHeapGrowth(_) | - &Instruction::CallGetAttributedVariableList(_) | - &Instruction::CallGetAttrVarQueueDelimiter(_) | - &Instruction::CallGetAttrVarQueueBeyond(_) | - &Instruction::CallGetBValue(_) | - &Instruction::CallGetContinuationChunk(_) | - &Instruction::CallGetNextOpDBRef(_) | - &Instruction::CallLookupDBRef(_) | - &Instruction::CallIsPartialString(_) | - &Instruction::CallHalt(_) | - &Instruction::CallGetLiftedHeapFromOffset(_) | - &Instruction::CallGetLiftedHeapFromOffsetDiff(_) | - &Instruction::CallGetSCCCleaner(_) | - &Instruction::CallHeadIsDynamic(_) | - &Instruction::CallInstallSCCCleaner(_) | - &Instruction::CallInstallInferenceCounter(_) | - &Instruction::CallLiftedHeapLength(_) | - &Instruction::CallLoadLibraryAsStream(_) | - &Instruction::CallModuleExists(_) | - &Instruction::CallNextEP(_) | - &Instruction::CallNoSuchPredicate(_) | - &Instruction::CallNumberToChars(_) | - &Instruction::CallNumberToCodes(_) | - &Instruction::CallOpDeclaration(_) | - &Instruction::CallOpen(_) | - &Instruction::CallSetStreamOptions(_) | - &Instruction::CallNextStream(_) | - &Instruction::CallPartialStringTail(_) | - &Instruction::CallPeekByte(_) | - &Instruction::CallPeekChar(_) | - &Instruction::CallPeekCode(_) | - &Instruction::CallPointsToContinuationResetMarker(_) | - &Instruction::CallPutByte(_) | - &Instruction::CallPutChar(_) | - &Instruction::CallPutChars(_) | - &Instruction::CallPutCode(_) | - &Instruction::CallReadQueryTerm(_) | - &Instruction::CallReadTerm(_) | - &Instruction::CallRedoAttrVarBinding(_) | - &Instruction::CallRemoveCallPolicyCheck(_) | - &Instruction::CallRemoveInferenceCounter(_) | - &Instruction::CallResetContinuationMarker(_) | - &Instruction::CallRestoreCutPolicy(_) | + &Instruction::CallCompileInlineOrExpandedGoal | + &Instruction::CallIsExpandedOrInlined | + &Instruction::CallGetClauseP | + &Instruction::CallInvokeClauseAtP | + &Instruction::CallGetFromAttributedVarList | + &Instruction::CallPutToAttributedVarList | + &Instruction::CallDeleteFromAttributedVarList | + &Instruction::CallDeleteAllAttributesFromVar | + &Instruction::CallUnattributedVar | + &Instruction::CallGetDBRefs | + &Instruction::CallFetchGlobalVar | + &Instruction::CallFirstStream | + &Instruction::CallFlushOutput | + &Instruction::CallGetByte | + &Instruction::CallGetChar | + &Instruction::CallGetNChars | + &Instruction::CallGetCode | + &Instruction::CallGetSingleChar | + &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff | + &Instruction::CallTruncateIfNoLiftedHeapGrowth | + &Instruction::CallGetAttributedVariableList | + &Instruction::CallGetAttrVarQueueDelimiter | + &Instruction::CallGetAttrVarQueueBeyond | + &Instruction::CallGetBValue | + &Instruction::CallGetContinuationChunk | + &Instruction::CallGetNextOpDBRef | + &Instruction::CallLookupDBRef | + &Instruction::CallIsPartialString | + &Instruction::CallHalt | + &Instruction::CallGetLiftedHeapFromOffset | + &Instruction::CallGetLiftedHeapFromOffsetDiff | + &Instruction::CallGetSCCCleaner | + &Instruction::CallHeadIsDynamic | + &Instruction::CallInstallSCCCleaner | + &Instruction::CallInstallInferenceCounter | + &Instruction::CallLiftedHeapLength | + &Instruction::CallLoadLibraryAsStream | + &Instruction::CallModuleExists | + &Instruction::CallNextEP | + &Instruction::CallNoSuchPredicate | + &Instruction::CallNumberToChars | + &Instruction::CallNumberToCodes | + &Instruction::CallOpDeclaration | + &Instruction::CallOpen | + &Instruction::CallSetStreamOptions | + &Instruction::CallNextStream | + &Instruction::CallPartialStringTail | + &Instruction::CallPeekByte | + &Instruction::CallPeekChar | + &Instruction::CallPeekCode | + &Instruction::CallPointsToContinuationResetMarker | + &Instruction::CallPutByte | + &Instruction::CallPutChar | + &Instruction::CallPutChars | + &Instruction::CallPutCode | + &Instruction::CallReadQueryTerm | + &Instruction::CallReadTerm | + &Instruction::CallRedoAttrVarBinding | + &Instruction::CallRemoveCallPolicyCheck | + &Instruction::CallRemoveInferenceCounter | + &Instruction::CallResetContinuationMarker | + &Instruction::CallRestoreCutPolicy | &Instruction::CallSetCutPoint(..) | - &Instruction::CallSetInput(_) | - &Instruction::CallSetOutput(_) | - &Instruction::CallStoreBacktrackableGlobalVar(_) | - &Instruction::CallStoreGlobalVar(_) | - &Instruction::CallStreamProperty(_) | - &Instruction::CallSetStreamPosition(_) | - &Instruction::CallInferenceLevel(_) | - &Instruction::CallCleanUpBlock(_) | - &Instruction::CallFail(_) | - &Instruction::CallGetBall(_) | - &Instruction::CallGetCurrentBlock(_) | - &Instruction::CallGetCutPoint(_) | - &Instruction::CallGetDoubleQuotes(_) | - &Instruction::CallInstallNewBlock(_) | - &Instruction::CallMaybe(_) | - &Instruction::CallCpuNow(_) | - &Instruction::CallDeterministicLengthRundown(_) | - &Instruction::CallHttpOpen(_) | - &Instruction::CallHttpListen(_) | - &Instruction::CallHttpAccept(_) | - &Instruction::CallHttpAnswer(_) | - &Instruction::CallLoadForeignLib(_) | - &Instruction::CallForeignCall(_) | - &Instruction::CallDefineForeignStruct(_) | - &Instruction::CallPredicateDefined(_) | - &Instruction::CallStripModule(_) | - &Instruction::CallCurrentTime(_) | - &Instruction::CallQuotedToken(_) | - &Instruction::CallReadTermFromChars(_) | - &Instruction::CallResetBlock(_) | - &Instruction::CallReturnFromVerifyAttr(_) | - &Instruction::CallSetBall(_) | - &Instruction::CallPushBallStack(_) | - &Instruction::CallPopBallStack(_) | - &Instruction::CallPopFromBallStack(_) | + &Instruction::CallSetInput | + &Instruction::CallSetOutput | + &Instruction::CallStoreBacktrackableGlobalVar | + &Instruction::CallStoreGlobalVar | + &Instruction::CallStreamProperty | + &Instruction::CallSetStreamPosition | + &Instruction::CallInferenceLevel | + &Instruction::CallCleanUpBlock | + &Instruction::CallFail | + &Instruction::CallGetBall | + &Instruction::CallGetCurrentBlock | + &Instruction::CallGetCutPoint | + &Instruction::CallGetDoubleQuotes | + &Instruction::CallInstallNewBlock | + &Instruction::CallMaybe | + &Instruction::CallCpuNow | + &Instruction::CallDeterministicLengthRundown | + &Instruction::CallHttpOpen | + &Instruction::CallHttpListen | + &Instruction::CallHttpAccept | + &Instruction::CallHttpAnswer | + &Instruction::CallLoadForeignLib | + &Instruction::CallForeignCall | + &Instruction::CallDefineForeignStruct | + &Instruction::CallPredicateDefined | + &Instruction::CallStripModule | + &Instruction::CallCurrentTime | + &Instruction::CallQuotedToken | + &Instruction::CallReadTermFromChars | + &Instruction::CallResetBlock | + &Instruction::CallReturnFromVerifyAttr | + &Instruction::CallSetBall | + &Instruction::CallPushBallStack | + &Instruction::CallPopBallStack | + &Instruction::CallPopFromBallStack | &Instruction::CallSetCutPointByDefault(..) | - &Instruction::CallSetDoubleQuotes(_) | - &Instruction::CallSetSeed(_) | - &Instruction::CallSkipMaxList(_) | - &Instruction::CallSleep(_) | - &Instruction::CallSocketClientOpen(_) | - &Instruction::CallSocketServerOpen(_) | - &Instruction::CallSocketServerAccept(_) | - &Instruction::CallSocketServerClose(_) | - &Instruction::CallTLSAcceptClient(_) | - &Instruction::CallTLSClientConnect(_) | - &Instruction::CallSucceed(_) | - &Instruction::CallTermAttributedVariables(_) | - &Instruction::CallTermVariables(_) | - &Instruction::CallTermVariablesUnderMaxDepth(_) | - &Instruction::CallTruncateLiftedHeapTo(_) | - &Instruction::CallUnifyWithOccursCheck(_) | - &Instruction::CallUnwindEnvironments(_) | - &Instruction::CallUnwindStack(_) | - &Instruction::CallWAMInstructions(_) | - &Instruction::CallInlinedInstructions(_) | - &Instruction::CallWriteTerm(_) | - &Instruction::CallWriteTermToChars(_) | - &Instruction::CallScryerPrologVersion(_) | - &Instruction::CallCryptoRandomByte(_) | - &Instruction::CallCryptoDataHash(_) | - &Instruction::CallCryptoDataHKDF(_) | - &Instruction::CallCryptoPasswordHash(_) | - &Instruction::CallCryptoDataEncrypt(_) | - &Instruction::CallCryptoDataDecrypt(_) | - &Instruction::CallCryptoCurveScalarMult(_) | - &Instruction::CallEd25519Sign(_) | - &Instruction::CallEd25519Verify(_) | - &Instruction::CallEd25519NewKeyPair(_) | - &Instruction::CallEd25519KeyPairPublicKey(_) | - &Instruction::CallCurve25519ScalarMult(_) | - &Instruction::CallFirstNonOctet(_) | - &Instruction::CallLoadHTML(_) | - &Instruction::CallLoadXML(_) | - &Instruction::CallGetEnv(_) | - &Instruction::CallSetEnv(_) | - &Instruction::CallUnsetEnv(_) | - &Instruction::CallShell(_) | - &Instruction::CallPID(_) | - &Instruction::CallCharsBase64(_) | - &Instruction::CallDevourWhitespace(_) | - &Instruction::CallIsSTOEnabled(_) | - &Instruction::CallSetSTOAsUnify(_) | - &Instruction::CallSetNSTOAsUnify(_) | - &Instruction::CallSetSTOWithErrorAsUnify(_) | - &Instruction::CallHomeDirectory(_) | - &Instruction::CallDebugHook(_) | - &Instruction::CallAddDiscontiguousPredicate(_) | - &Instruction::CallAddDynamicPredicate(_) | - &Instruction::CallAddMultifilePredicate(_) | - &Instruction::CallAddGoalExpansionClause(_) | - &Instruction::CallAddTermExpansionClause(_) | - &Instruction::CallAddInSituFilenameModule(_) | - &Instruction::CallClauseToEvacuable(_) | - &Instruction::CallScopedClauseToEvacuable(_) | - &Instruction::CallConcludeLoad(_) | - &Instruction::CallDeclareModule(_) | - &Instruction::CallLoadCompiledLibrary(_) | - &Instruction::CallLoadContextSource(_) | - &Instruction::CallLoadContextFile(_) | - &Instruction::CallLoadContextDirectory(_) | - &Instruction::CallLoadContextModule(_) | - &Instruction::CallLoadContextStream(_) | - &Instruction::CallPopLoadContext(_) | - &Instruction::CallPopLoadStatePayload(_) | - &Instruction::CallPushLoadContext(_) | - &Instruction::CallPushLoadStatePayload(_) | - &Instruction::CallUseModule(_) | - &Instruction::CallBuiltInProperty(_) | - &Instruction::CallMetaPredicateProperty(_) | - &Instruction::CallMultifileProperty(_) | - &Instruction::CallDiscontiguousProperty(_) | - &Instruction::CallDynamicProperty(_) | - &Instruction::CallAbolishClause(_) | - &Instruction::CallAsserta(_) | - &Instruction::CallAssertz(_) | - &Instruction::CallRetract(_) | - &Instruction::CallIsConsistentWithTermQueue(_) | - &Instruction::CallFlushTermQueue(_) | - &Instruction::CallRemoveModuleExports(_) | - &Instruction::CallAddNonCountedBacktracking(_) | - &Instruction::CallPopCount(_) => { + &Instruction::CallSetDoubleQuotes | + &Instruction::CallSetSeed | + &Instruction::CallSkipMaxList | + &Instruction::CallSleep | + &Instruction::CallSocketClientOpen | + &Instruction::CallSocketServerOpen | + &Instruction::CallSocketServerAccept | + &Instruction::CallSocketServerClose | + &Instruction::CallTLSAcceptClient | + &Instruction::CallTLSClientConnect | + &Instruction::CallSucceed | + &Instruction::CallTermAttributedVariables | + &Instruction::CallTermVariables | + &Instruction::CallTermVariablesUnderMaxDepth | + &Instruction::CallTruncateLiftedHeapTo | + &Instruction::CallUnifyWithOccursCheck | + &Instruction::CallUnwindEnvironments | + &Instruction::CallUnwindStack | + &Instruction::CallWAMInstructions | + &Instruction::CallInlinedInstructions | + &Instruction::CallWriteTerm | + &Instruction::CallWriteTermToChars | + &Instruction::CallScryerPrologVersion | + &Instruction::CallCryptoRandomByte | + &Instruction::CallCryptoDataHash | + &Instruction::CallCryptoDataHKDF | + &Instruction::CallCryptoPasswordHash | + &Instruction::CallCryptoDataEncrypt | + &Instruction::CallCryptoDataDecrypt | + &Instruction::CallCryptoCurveScalarMult | + &Instruction::CallEd25519Sign | + &Instruction::CallEd25519Verify | + &Instruction::CallEd25519NewKeyPair | + &Instruction::CallEd25519KeyPairPublicKey | + &Instruction::CallCurve25519ScalarMult | + &Instruction::CallFirstNonOctet | + &Instruction::CallLoadHTML | + &Instruction::CallLoadXML | + &Instruction::CallGetEnv | + &Instruction::CallSetEnv | + &Instruction::CallUnsetEnv | + &Instruction::CallShell | + &Instruction::CallPID | + &Instruction::CallCharsBase64 | + &Instruction::CallDevourWhitespace | + &Instruction::CallIsSTOEnabled | + &Instruction::CallSetSTOAsUnify | + &Instruction::CallSetNSTOAsUnify | + &Instruction::CallSetSTOWithErrorAsUnify | + &Instruction::CallHomeDirectory | + &Instruction::CallDebugHook | + &Instruction::CallAddDiscontiguousPredicate | + &Instruction::CallAddDynamicPredicate | + &Instruction::CallAddMultifilePredicate | + &Instruction::CallAddGoalExpansionClause | + &Instruction::CallAddTermExpansionClause | + &Instruction::CallAddInSituFilenameModule | + &Instruction::CallClauseToEvacuable | + &Instruction::CallScopedClauseToEvacuable | + &Instruction::CallConcludeLoad | + &Instruction::CallDeclareModule | + &Instruction::CallLoadCompiledLibrary | + &Instruction::CallLoadContextSource | + &Instruction::CallLoadContextFile | + &Instruction::CallLoadContextDirectory | + &Instruction::CallLoadContextModule | + &Instruction::CallLoadContextStream | + &Instruction::CallPopLoadContext | + &Instruction::CallPopLoadStatePayload | + &Instruction::CallPushLoadContext | + &Instruction::CallPushLoadStatePayload | + &Instruction::CallUseModule | + &Instruction::CallBuiltInProperty | + &Instruction::CallMetaPredicateProperty | + &Instruction::CallMultifileProperty | + &Instruction::CallDiscontiguousProperty | + &Instruction::CallDynamicProperty | + &Instruction::CallAbolishClause | + &Instruction::CallAsserta | + &Instruction::CallAssertz | + &Instruction::CallRetract | + &Instruction::CallIsConsistentWithTermQueue | + &Instruction::CallFlushTermQueue | + &Instruction::CallRemoveModuleExports | + &Instruction::CallAddNonCountedBacktracking | + &Instruction::CallPopCount => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("call"), [atom(name), fixnum(arity)]) } // - &Instruction::ExecuteAtomChars(_) | - &Instruction::ExecuteAtomCodes(_) | - &Instruction::ExecuteAtomLength(_) | - &Instruction::ExecuteBindFromRegister(_) | - &Instruction::ExecuteContinuation(_) | - &Instruction::ExecuteCharCode(_) | - &Instruction::ExecuteCharType(_) | - &Instruction::ExecuteCharsToNumber(_) | - &Instruction::ExecuteCodesToNumber(_) | - &Instruction::ExecuteCopyTermWithoutAttrVars(_) | - &Instruction::ExecuteCheckCutPoint(_) | - &Instruction::ExecuteClose(_) | - &Instruction::ExecuteCopyToLiftedHeap(_) | - &Instruction::ExecuteCreatePartialString(_) | - &Instruction::ExecuteCurrentHostname(_) | - &Instruction::ExecuteCurrentInput(_) | - &Instruction::ExecuteCurrentOutput(_) | - &Instruction::ExecuteDirectoryFiles(_) | - &Instruction::ExecuteFileSize(_) | - &Instruction::ExecuteFileExists(_) | - &Instruction::ExecuteDirectoryExists(_) | - &Instruction::ExecuteDirectorySeparator(_) | - &Instruction::ExecuteMakeDirectory(_) | - &Instruction::ExecuteMakeDirectoryPath(_) | - &Instruction::ExecuteDeleteFile(_) | - &Instruction::ExecuteRenameFile(_) | - &Instruction::ExecuteFileCopy(_) | - &Instruction::ExecuteWorkingDirectory(_) | - &Instruction::ExecuteDeleteDirectory(_) | - &Instruction::ExecutePathCanonical(_) | - &Instruction::ExecuteFileTime(_) | + &Instruction::ExecuteAtomChars | + &Instruction::ExecuteAtomCodes | + &Instruction::ExecuteAtomLength | + &Instruction::ExecuteBindFromRegister | + &Instruction::ExecuteContinuation | + &Instruction::ExecuteCharCode | + &Instruction::ExecuteCharType | + &Instruction::ExecuteCharsToNumber | + &Instruction::ExecuteCodesToNumber | + &Instruction::ExecuteCopyTermWithoutAttrVars | + &Instruction::ExecuteCheckCutPoint | + &Instruction::ExecuteClose | + &Instruction::ExecuteCopyToLiftedHeap | + &Instruction::ExecuteCreatePartialString | + &Instruction::ExecuteCurrentHostname | + &Instruction::ExecuteCurrentInput | + &Instruction::ExecuteCurrentOutput | + &Instruction::ExecuteDirectoryFiles | + &Instruction::ExecuteFileSize | + &Instruction::ExecuteFileExists | + &Instruction::ExecuteDirectoryExists | + &Instruction::ExecuteDirectorySeparator | + &Instruction::ExecuteMakeDirectory | + &Instruction::ExecuteMakeDirectoryPath | + &Instruction::ExecuteDeleteFile | + &Instruction::ExecuteRenameFile | + &Instruction::ExecuteFileCopy | + &Instruction::ExecuteWorkingDirectory | + &Instruction::ExecuteDeleteDirectory | + &Instruction::ExecutePathCanonical | + &Instruction::ExecuteFileTime | &Instruction::ExecuteDynamicModuleResolution(..) | &Instruction::ExecutePrepareCallClause(..) | - &Instruction::ExecuteCompileInlineOrExpandedGoal(..) | - &Instruction::ExecuteIsExpandedOrInlined(_) | - &Instruction::ExecuteGetClauseP(_) | - &Instruction::ExecuteInvokeClauseAtP(_) | - &Instruction::ExecuteGetFromAttributedVarList(_) | - &Instruction::ExecutePutToAttributedVarList(_) | - &Instruction::ExecuteDeleteFromAttributedVarList(_) | - &Instruction::ExecuteDeleteAllAttributesFromVar(_) | - &Instruction::ExecuteUnattributedVar(_) | - &Instruction::ExecuteGetDBRefs(_) | - &Instruction::ExecuteFetchGlobalVar(_) | - &Instruction::ExecuteFirstStream(_) | - &Instruction::ExecuteFlushOutput(_) | - &Instruction::ExecuteGetByte(_) | - &Instruction::ExecuteGetChar(_) | - &Instruction::ExecuteGetNChars(_) | - &Instruction::ExecuteGetCode(_) | - &Instruction::ExecuteGetSingleChar(_) | - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff(_) | - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth(_) | - &Instruction::ExecuteGetAttributedVariableList(_) | - &Instruction::ExecuteGetAttrVarQueueDelimiter(_) | - &Instruction::ExecuteGetAttrVarQueueBeyond(_) | - &Instruction::ExecuteGetBValue(_) | - &Instruction::ExecuteGetContinuationChunk(_) | - &Instruction::ExecuteGetNextOpDBRef(_) | - &Instruction::ExecuteLookupDBRef(_) | - &Instruction::ExecuteIsPartialString(_) | - &Instruction::ExecuteHalt(_) | - &Instruction::ExecuteGetLiftedHeapFromOffset(_) | - &Instruction::ExecuteGetLiftedHeapFromOffsetDiff(_) | - &Instruction::ExecuteGetSCCCleaner(_) | - &Instruction::ExecuteHeadIsDynamic(_) | - &Instruction::ExecuteInstallSCCCleaner(_) | - &Instruction::ExecuteInstallInferenceCounter(_) | - &Instruction::ExecuteLiftedHeapLength(_) | - &Instruction::ExecuteLoadLibraryAsStream(_) | - &Instruction::ExecuteModuleExists(_) | - &Instruction::ExecuteNextEP(_) | - &Instruction::ExecuteNoSuchPredicate(_) | - &Instruction::ExecuteNumberToChars(_) | - &Instruction::ExecuteNumberToCodes(_) | - &Instruction::ExecuteOpDeclaration(_) | - &Instruction::ExecuteOpen(_) | - &Instruction::ExecuteSetStreamOptions(_) | - &Instruction::ExecuteNextStream(_) | - &Instruction::ExecutePartialStringTail(_) | - &Instruction::ExecutePeekByte(_) | - &Instruction::ExecutePeekChar(_) | - &Instruction::ExecutePeekCode(_) | - &Instruction::ExecutePointsToContinuationResetMarker(_) | - &Instruction::ExecutePutByte(_) | - &Instruction::ExecutePutChar(_) | - &Instruction::ExecutePutChars(_) | - &Instruction::ExecutePutCode(_) | - &Instruction::ExecuteReadQueryTerm(_) | - &Instruction::ExecuteReadTerm(_) | - &Instruction::ExecuteRedoAttrVarBinding(_) | - &Instruction::ExecuteRemoveCallPolicyCheck(_) | - &Instruction::ExecuteRemoveInferenceCounter(_) | - &Instruction::ExecuteResetContinuationMarker(_) | - &Instruction::ExecuteRestoreCutPolicy(_) | - &Instruction::ExecuteSetCutPoint(_, _) | - &Instruction::ExecuteSetInput(_) | - &Instruction::ExecuteSetOutput(_) | - &Instruction::ExecuteStoreBacktrackableGlobalVar(_) | - &Instruction::ExecuteStoreGlobalVar(_) | - &Instruction::ExecuteStreamProperty(_) | - &Instruction::ExecuteSetStreamPosition(_) | - &Instruction::ExecuteInferenceLevel(_) | - &Instruction::ExecuteCleanUpBlock(_) | - &Instruction::ExecuteFail(_) | - &Instruction::ExecuteGetBall(_) | - &Instruction::ExecuteGetCurrentBlock(_) | - &Instruction::ExecuteGetCutPoint(_) | - &Instruction::ExecuteGetDoubleQuotes(_) | - &Instruction::ExecuteInstallNewBlock(_) | - &Instruction::ExecuteMaybe(_) | - &Instruction::ExecuteCpuNow(_) | - &Instruction::ExecuteDeterministicLengthRundown(_) | - &Instruction::ExecuteHttpOpen(_) | - &Instruction::ExecuteHttpListen(_) | - &Instruction::ExecuteHttpAccept(_) | - &Instruction::ExecuteHttpAnswer(_) | - &Instruction::ExecuteLoadForeignLib(_) | - &Instruction::ExecuteForeignCall(_) | - &Instruction::ExecuteDefineForeignStruct(_) | - &Instruction::ExecutePredicateDefined(_) | - &Instruction::ExecuteStripModule(_) | - &Instruction::ExecuteCurrentTime(_) | - &Instruction::ExecuteQuotedToken(_) | - &Instruction::ExecuteReadTermFromChars(_) | - &Instruction::ExecuteResetBlock(_) | - &Instruction::ExecuteReturnFromVerifyAttr(_) | - &Instruction::ExecuteSetBall(_) | - &Instruction::ExecutePushBallStack(_) | - &Instruction::ExecutePopBallStack(_) | - &Instruction::ExecutePopFromBallStack(_) | - &Instruction::ExecuteSetCutPointByDefault(_, _) | - &Instruction::ExecuteSetDoubleQuotes(_) | - &Instruction::ExecuteSetSeed(_) | - &Instruction::ExecuteSkipMaxList(_) | - &Instruction::ExecuteSleep(_) | - &Instruction::ExecuteSocketClientOpen(_) | - &Instruction::ExecuteSocketServerOpen(_) | - &Instruction::ExecuteSocketServerAccept(_) | - &Instruction::ExecuteSocketServerClose(_) | - &Instruction::ExecuteTLSAcceptClient(_) | - &Instruction::ExecuteTLSClientConnect(_) | - &Instruction::ExecuteSucceed(_) | - &Instruction::ExecuteTermAttributedVariables(_) | - &Instruction::ExecuteTermVariables(_) | - &Instruction::ExecuteTermVariablesUnderMaxDepth(_) | - &Instruction::ExecuteTruncateLiftedHeapTo(_) | - &Instruction::ExecuteUnifyWithOccursCheck(_) | - &Instruction::ExecuteUnwindEnvironments(_) | - &Instruction::ExecuteUnwindStack(_) | - &Instruction::ExecuteWAMInstructions(_) | - &Instruction::ExecuteInlinedInstructions(_) | - &Instruction::ExecuteWriteTerm(_) | - &Instruction::ExecuteWriteTermToChars(_) | - &Instruction::ExecuteScryerPrologVersion(_) | - &Instruction::ExecuteCryptoRandomByte(_) | - &Instruction::ExecuteCryptoDataHash(_) | - &Instruction::ExecuteCryptoDataHKDF(_) | - &Instruction::ExecuteCryptoPasswordHash(_) | - &Instruction::ExecuteCryptoDataEncrypt(_) | - &Instruction::ExecuteCryptoDataDecrypt(_) | - &Instruction::ExecuteCryptoCurveScalarMult(_) | - &Instruction::ExecuteEd25519Sign(_) | - &Instruction::ExecuteEd25519Verify(_) | - &Instruction::ExecuteEd25519NewKeyPair(_) | - &Instruction::ExecuteEd25519KeyPairPublicKey(_) | - &Instruction::ExecuteCurve25519ScalarMult(_) | - &Instruction::ExecuteFirstNonOctet(_) | - &Instruction::ExecuteLoadHTML(_) | - &Instruction::ExecuteLoadXML(_) | - &Instruction::ExecuteGetEnv(_) | - &Instruction::ExecuteSetEnv(_) | - &Instruction::ExecuteUnsetEnv(_) | - &Instruction::ExecuteShell(_) | - &Instruction::ExecutePID(_) | - &Instruction::ExecuteCharsBase64(_) | - &Instruction::ExecuteDevourWhitespace(_) | - &Instruction::ExecuteIsSTOEnabled(_) | - &Instruction::ExecuteSetSTOAsUnify(_) | - &Instruction::ExecuteSetNSTOAsUnify(_) | - &Instruction::ExecuteSetSTOWithErrorAsUnify(_) | - &Instruction::ExecuteHomeDirectory(_) | - &Instruction::ExecuteDebugHook(_) | - &Instruction::ExecuteAddDiscontiguousPredicate(_) | - &Instruction::ExecuteAddDynamicPredicate(_) | - &Instruction::ExecuteAddMultifilePredicate(_) | - &Instruction::ExecuteAddGoalExpansionClause(_) | - &Instruction::ExecuteAddTermExpansionClause(_) | - &Instruction::ExecuteAddInSituFilenameModule(_) | - &Instruction::ExecuteClauseToEvacuable(_) | - &Instruction::ExecuteScopedClauseToEvacuable(_) | - &Instruction::ExecuteConcludeLoad(_) | - &Instruction::ExecuteDeclareModule(_) | - &Instruction::ExecuteLoadCompiledLibrary(_) | - &Instruction::ExecuteLoadContextSource(_) | - &Instruction::ExecuteLoadContextFile(_) | - &Instruction::ExecuteLoadContextDirectory(_) | - &Instruction::ExecuteLoadContextModule(_) | - &Instruction::ExecuteLoadContextStream(_) | - &Instruction::ExecutePopLoadContext(_) | - &Instruction::ExecutePopLoadStatePayload(_) | - &Instruction::ExecutePushLoadContext(_) | - &Instruction::ExecutePushLoadStatePayload(_) | - &Instruction::ExecuteUseModule(_) | - &Instruction::ExecuteBuiltInProperty(_) | - &Instruction::ExecuteMetaPredicateProperty(_) | - &Instruction::ExecuteMultifileProperty(_) | - &Instruction::ExecuteDiscontiguousProperty(_) | - &Instruction::ExecuteDynamicProperty(_) | - &Instruction::ExecuteAbolishClause(_) | - &Instruction::ExecuteAsserta(_) | - &Instruction::ExecuteAssertz(_) | - &Instruction::ExecuteRetract(_) | - &Instruction::ExecuteIsConsistentWithTermQueue(_) | - &Instruction::ExecuteFlushTermQueue(_) | - &Instruction::ExecuteRemoveModuleExports(_) | - &Instruction::ExecuteAddNonCountedBacktracking(_) | - &Instruction::ExecutePopCount(_) => { + &Instruction::ExecuteCompileInlineOrExpandedGoal | + &Instruction::ExecuteIsExpandedOrInlined | + &Instruction::ExecuteGetClauseP | + &Instruction::ExecuteInvokeClauseAtP | + &Instruction::ExecuteGetFromAttributedVarList | + &Instruction::ExecutePutToAttributedVarList | + &Instruction::ExecuteDeleteFromAttributedVarList | + &Instruction::ExecuteDeleteAllAttributesFromVar | + &Instruction::ExecuteUnattributedVar | + &Instruction::ExecuteGetDBRefs | + &Instruction::ExecuteFetchGlobalVar | + &Instruction::ExecuteFirstStream | + &Instruction::ExecuteFlushOutput | + &Instruction::ExecuteGetByte | + &Instruction::ExecuteGetChar | + &Instruction::ExecuteGetNChars | + &Instruction::ExecuteGetCode | + &Instruction::ExecuteGetSingleChar | + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff | + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth | + &Instruction::ExecuteGetAttributedVariableList | + &Instruction::ExecuteGetAttrVarQueueDelimiter | + &Instruction::ExecuteGetAttrVarQueueBeyond | + &Instruction::ExecuteGetBValue | + &Instruction::ExecuteGetContinuationChunk | + &Instruction::ExecuteGetNextOpDBRef | + &Instruction::ExecuteLookupDBRef | + &Instruction::ExecuteIsPartialString | + &Instruction::ExecuteHalt | + &Instruction::ExecuteGetLiftedHeapFromOffset | + &Instruction::ExecuteGetLiftedHeapFromOffsetDiff | + &Instruction::ExecuteGetSCCCleaner | + &Instruction::ExecuteHeadIsDynamic | + &Instruction::ExecuteInstallSCCCleaner | + &Instruction::ExecuteInstallInferenceCounter | + &Instruction::ExecuteLiftedHeapLength | + &Instruction::ExecuteLoadLibraryAsStream | + &Instruction::ExecuteModuleExists | + &Instruction::ExecuteNextEP | + &Instruction::ExecuteNoSuchPredicate | + &Instruction::ExecuteNumberToChars | + &Instruction::ExecuteNumberToCodes | + &Instruction::ExecuteOpDeclaration | + &Instruction::ExecuteOpen | + &Instruction::ExecuteSetStreamOptions | + &Instruction::ExecuteNextStream | + &Instruction::ExecutePartialStringTail | + &Instruction::ExecutePeekByte | + &Instruction::ExecutePeekChar | + &Instruction::ExecutePeekCode | + &Instruction::ExecutePointsToContinuationResetMarker | + &Instruction::ExecutePutByte | + &Instruction::ExecutePutChar | + &Instruction::ExecutePutChars | + &Instruction::ExecutePutCode | + &Instruction::ExecuteReadQueryTerm | + &Instruction::ExecuteReadTerm | + &Instruction::ExecuteRedoAttrVarBinding | + &Instruction::ExecuteRemoveCallPolicyCheck | + &Instruction::ExecuteRemoveInferenceCounter | + &Instruction::ExecuteResetContinuationMarker | + &Instruction::ExecuteRestoreCutPolicy | + &Instruction::ExecuteSetCutPoint(_) | + &Instruction::ExecuteSetInput | + &Instruction::ExecuteSetOutput | + &Instruction::ExecuteStoreBacktrackableGlobalVar | + &Instruction::ExecuteStoreGlobalVar | + &Instruction::ExecuteStreamProperty | + &Instruction::ExecuteSetStreamPosition | + &Instruction::ExecuteInferenceLevel | + &Instruction::ExecuteCleanUpBlock | + &Instruction::ExecuteFail | + &Instruction::ExecuteGetBall | + &Instruction::ExecuteGetCurrentBlock | + &Instruction::ExecuteGetCutPoint | + &Instruction::ExecuteGetDoubleQuotes | + &Instruction::ExecuteInstallNewBlock | + &Instruction::ExecuteMaybe | + &Instruction::ExecuteCpuNow | + &Instruction::ExecuteDeterministicLengthRundown | + &Instruction::ExecuteHttpOpen | + &Instruction::ExecuteHttpListen | + &Instruction::ExecuteHttpAccept | + &Instruction::ExecuteHttpAnswer | + &Instruction::ExecuteLoadForeignLib | + &Instruction::ExecuteForeignCall | + &Instruction::ExecuteDefineForeignStruct | + &Instruction::ExecutePredicateDefined | + &Instruction::ExecuteStripModule | + &Instruction::ExecuteCurrentTime | + &Instruction::ExecuteQuotedToken | + &Instruction::ExecuteReadTermFromChars | + &Instruction::ExecuteResetBlock | + &Instruction::ExecuteReturnFromVerifyAttr | + &Instruction::ExecuteSetBall | + &Instruction::ExecutePushBallStack | + &Instruction::ExecutePopBallStack | + &Instruction::ExecutePopFromBallStack | + &Instruction::ExecuteSetCutPointByDefault(_) | + &Instruction::ExecuteSetDoubleQuotes | + &Instruction::ExecuteSetSeed | + &Instruction::ExecuteSkipMaxList | + &Instruction::ExecuteSleep | + &Instruction::ExecuteSocketClientOpen | + &Instruction::ExecuteSocketServerOpen | + &Instruction::ExecuteSocketServerAccept | + &Instruction::ExecuteSocketServerClose | + &Instruction::ExecuteTLSAcceptClient | + &Instruction::ExecuteTLSClientConnect | + &Instruction::ExecuteSucceed | + &Instruction::ExecuteTermAttributedVariables | + &Instruction::ExecuteTermVariables | + &Instruction::ExecuteTermVariablesUnderMaxDepth | + &Instruction::ExecuteTruncateLiftedHeapTo | + &Instruction::ExecuteUnifyWithOccursCheck | + &Instruction::ExecuteUnwindEnvironments | + &Instruction::ExecuteUnwindStack | + &Instruction::ExecuteWAMInstructions | + &Instruction::ExecuteInlinedInstructions | + &Instruction::ExecuteWriteTerm | + &Instruction::ExecuteWriteTermToChars | + &Instruction::ExecuteScryerPrologVersion | + &Instruction::ExecuteCryptoRandomByte | + &Instruction::ExecuteCryptoDataHash | + &Instruction::ExecuteCryptoDataHKDF | + &Instruction::ExecuteCryptoPasswordHash | + &Instruction::ExecuteCryptoDataEncrypt | + &Instruction::ExecuteCryptoDataDecrypt | + &Instruction::ExecuteCryptoCurveScalarMult | + &Instruction::ExecuteEd25519Sign | + &Instruction::ExecuteEd25519Verify | + &Instruction::ExecuteEd25519NewKeyPair | + &Instruction::ExecuteEd25519KeyPairPublicKey | + &Instruction::ExecuteCurve25519ScalarMult | + &Instruction::ExecuteFirstNonOctet | + &Instruction::ExecuteLoadHTML | + &Instruction::ExecuteLoadXML | + &Instruction::ExecuteGetEnv | + &Instruction::ExecuteSetEnv | + &Instruction::ExecuteUnsetEnv | + &Instruction::ExecuteShell | + &Instruction::ExecutePID | + &Instruction::ExecuteCharsBase64 | + &Instruction::ExecuteDevourWhitespace | + &Instruction::ExecuteIsSTOEnabled | + &Instruction::ExecuteSetSTOAsUnify | + &Instruction::ExecuteSetNSTOAsUnify | + &Instruction::ExecuteSetSTOWithErrorAsUnify | + &Instruction::ExecuteHomeDirectory | + &Instruction::ExecuteDebugHook | + &Instruction::ExecuteAddDiscontiguousPredicate | + &Instruction::ExecuteAddDynamicPredicate | + &Instruction::ExecuteAddMultifilePredicate | + &Instruction::ExecuteAddGoalExpansionClause | + &Instruction::ExecuteAddTermExpansionClause | + &Instruction::ExecuteAddInSituFilenameModule | + &Instruction::ExecuteClauseToEvacuable | + &Instruction::ExecuteScopedClauseToEvacuable | + &Instruction::ExecuteConcludeLoad | + &Instruction::ExecuteDeclareModule | + &Instruction::ExecuteLoadCompiledLibrary | + &Instruction::ExecuteLoadContextSource | + &Instruction::ExecuteLoadContextFile | + &Instruction::ExecuteLoadContextDirectory | + &Instruction::ExecuteLoadContextModule | + &Instruction::ExecuteLoadContextStream | + &Instruction::ExecutePopLoadContext | + &Instruction::ExecutePopLoadStatePayload | + &Instruction::ExecutePushLoadContext | + &Instruction::ExecutePushLoadStatePayload | + &Instruction::ExecuteUseModule | + &Instruction::ExecuteBuiltInProperty | + &Instruction::ExecuteMetaPredicateProperty | + &Instruction::ExecuteMultifileProperty | + &Instruction::ExecuteDiscontiguousProperty | + &Instruction::ExecuteDynamicProperty | + &Instruction::ExecuteAbolishClause | + &Instruction::ExecuteAsserta | + &Instruction::ExecuteAssertz | + &Instruction::ExecuteRetract | + &Instruction::ExecuteIsConsistentWithTermQueue | + &Instruction::ExecuteFlushTermQueue | + &Instruction::ExecuteRemoveModuleExports | + &Instruction::ExecuteAddNonCountedBacktracking | + &Instruction::ExecutePopCount => { let (name, arity) = self.to_name_and_arity(); functor!(atom!("execute"), [atom(name), fixnum(arity)]) } @@ -2048,12 +2053,9 @@ fn generate_instruction_preface() -> TokenStream { &Instruction::Deallocate => { functor!(atom!("deallocate")) } - &Instruction::JmpByCall(_, offset, ..) => { + &Instruction::JmpByCall(offset) => { functor!(atom!("jmp_by_call"), [fixnum(offset)]) } - &Instruction::JmpByExecute(_, offset, ..) => { - functor!(atom!("jmp_by_execute"), [fixnum(offset)]) - } &Instruction::RevJmpBy(offset) => { functor!(atom!("rev_jmp_by"), [fixnum(offset)]) } @@ -2248,6 +2250,7 @@ pub fn generate_instructions_rs() -> TokenStream { let mut clause_type_to_instr_arms = vec![]; let mut clause_type_name_arms = vec![]; let mut is_inbuilt_arms = vec![]; + let mut is_inlined_arms = vec![]; for (name, arity, variant) in instr_data.compare_number_variants { let ident = variant.ident.clone(); @@ -2299,7 +2302,7 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::Inlined( InlinedClauseType::CompareNumber(CompareNumber::#ident(#(#placeholder_ids),*)) - ) => Instruction::#instr_ident(#(#placeholder_ids),*, 0) + ) => Instruction::#instr_ident(#(*#placeholder_ids),*) } ); @@ -2308,6 +2311,12 @@ pub fn generate_instructions_rs() -> TokenStream { (atom!(#name), #arity) => true } ); + + is_inlined_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.compare_term_variants { @@ -2334,7 +2343,7 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::BuiltIn( BuiltInClauseType::CompareTerm(CompareTerm::#ident) - ) => Instruction::#instr_ident(0) + ) => Instruction::#instr_ident } ); @@ -2395,13 +2404,13 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::BuiltIn( BuiltInClauseType::#ident(#(#placeholder_ids),*) - ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + ) => Instruction::#instr_ident(#(*#placeholder_ids),*) } } else { quote! { ClauseType::BuiltIn( BuiltInClauseType::#ident - ) => Instruction::#instr_ident(0) + ) => Instruction::#instr_ident } }); @@ -2466,7 +2475,7 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::Inlined( InlinedClauseType::#ident(#(#placeholder_ids),*) - ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + ) => Instruction::#instr_ident(*#(#placeholder_ids),*) } ); @@ -2475,6 +2484,12 @@ pub fn generate_instructions_rs() -> TokenStream { (atom!(#name), #arity) => true } ); + + is_inlined_arms.push( + quote! { + (atom!(#name), #arity) => true + } + ); } for (name, arity, variant) in instr_data.system_clause_type_variants { @@ -2556,13 +2571,13 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::System( SystemClauseType::#ident(#(#placeholder_ids),*) - ) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + ) => Instruction::#instr_ident(#(*#placeholder_ids),*) } } else { quote! { ClauseType::System( SystemClauseType::#ident - ) => Instruction::#instr_ident(0) + ) => Instruction::#instr_ident } }); @@ -2633,13 +2648,13 @@ pub fn generate_instructions_rs() -> TokenStream { quote! { ClauseType::System(SystemClauseType::REPL( REPLCodePtr::#ident(#(#placeholder_ids),*) - )) => Instruction::#instr_ident(#(#placeholder_ids),*,0) + )) => Instruction::#instr_ident(#(*#placeholder_ids),*) } } else { quote! { ClauseType::System(SystemClauseType::REPL( REPLCodePtr::#ident - )) => Instruction::#instr_ident(0) + )) => Instruction::#instr_ident } }); @@ -2659,7 +2674,7 @@ pub fn generate_instructions_rs() -> TokenStream { }); clause_type_to_instr_arms.push(quote! { - ClauseType::Named(arity, name, idx) => Instruction::CallNamed(arity, name, idx, 0) + ClauseType::Named(arity, name, idx) => Instruction::CallNamed(*arity, *name, *idx) }); clause_type_name_arms.push(quote! { @@ -2710,11 +2725,11 @@ pub fn generate_instructions_rs() -> TokenStream { clause_type_to_instr_arms.push(if !variant_fields.is_empty() { quote! { ClauseType::#ident(#(#placeholder_ids),*) => - Instruction::#ident(#(#placeholder_ids),*,0) + Instruction::#ident(#(*#placeholder_ids),*) } } else { quote! { - ClauseType::#ident => Instruction::#ident(0) + ClauseType::#ident => Instruction::#ident } }); @@ -2771,11 +2786,6 @@ pub fn generate_instructions_rs() -> TokenStream { Instruction::#execute_ident(#(#placeholder_ids),*) } }) - } else if variant_string == "JmpByCall" { - Some(quote! { - Instruction::JmpByCall(#(#placeholder_ids),*) => - Instruction::JmpByExecute(#(#placeholder_ids),*) - }) } else { None } @@ -2839,16 +2849,23 @@ pub fn generate_instructions_rs() -> TokenStream { let enum_arity = if let Fields::Unnamed(fields) = &variant.fields { fields.unnamed.len() } else { - unreachable!() + 0 }; let placeholder_ids: Vec<_> = (0 .. enum_arity) .map(|n| format_ident!("f_{}", n)) .collect(); - Some(quote! { - Instruction::#variant_ident(#(#placeholder_ids),*) => - Instruction::#def_variant_ident(#(#placeholder_ids),*) + Some(if enum_arity == 0 { + quote! { + Instruction::#variant_ident => + Instruction::#def_variant_ident + } + } else { + quote! { + Instruction::#variant_ident(#(#placeholder_ids),*) => + Instruction::#def_variant_ident(#(#placeholder_ids),*) + } }) } else { None @@ -2856,38 +2873,6 @@ pub fn generate_instructions_rs() -> TokenStream { }) .collect(); - let perm_vars_mut_arms: Vec<_> = instr_data.instr_variants - .iter() - .cloned() - .filter_map(|(_, _, _, variant)| { - if !is_callable(&variant.ident) && !is_jmp(&variant.ident) { - return None; - } - - let variant_ident = variant.ident.clone(); - let enum_arity = if let Fields::Unnamed(fields) = &variant.fields { - fields.unnamed.len() - } else { - 0 - }; - - let placeholder_ids: Vec<_> = (1 .. enum_arity) - .map(|_| format_ident!("_")) - .collect(); - - Some(if enum_arity == 1 { - quote! { - Instruction::#variant_ident(ref mut perm_vars) => Some(perm_vars) - } - } else { - quote! { - Instruction::#variant_ident(#(#placeholder_ids),*, ref mut perm_vars) => - Some(perm_vars) - } - }) - }) - .collect(); - let control_flow_arms: Vec<_> = instr_data.instr_variants .iter() .cloned() @@ -2896,10 +2881,22 @@ pub fn generate_instructions_rs() -> TokenStream { return None; } + let enum_arity = if let Fields::Unnamed(fields) = &variant.fields { + fields.unnamed.len() + } else { + 0 + }; + let variant_ident = variant.ident.clone(); - Some(quote! { - Instruction::#variant_ident(..) => true + Some(if enum_arity == 0 { + quote! { + Instruction::#variant_ident => true + } + } else { + quote! { + Instruction::#variant_ident(..) => true + } }) }) .collect(); @@ -2917,27 +2914,59 @@ pub fn generate_instructions_rs() -> TokenStream { }; Some(if variant_string.starts_with("Execute") { - quote! { - (#name, execute, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name, execute) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, execute, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else if variant_string.starts_with("Call") { - quote! { - (#name, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else if variant_string.starts_with("DefaultExecute") { - quote! { - (#name, execute, default, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name, execute, default) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, execute, default, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else if variant_string.starts_with("DefaultCall") { - quote! { - (#name, default, $($args:expr),*) => { - Instruction::#variant_ident($($args),*) + if arity == 0 { + quote! { + (#name, default) => { + Instruction::#variant_ident + } + } + } else { + quote! { + (#name, default, $($args:expr),*) => { + Instruction::#variant_ident($($args),*) + } } } } else { @@ -3065,7 +3094,7 @@ pub fn generate_instructions_rs() -> TokenStream { } } - pub fn to_instr(self) -> Instruction { + pub fn to_instr(&self) -> Instruction { match self { #( #clause_type_to_instr_arms, @@ -3089,6 +3118,15 @@ pub fn generate_instructions_rs() -> TokenStream { )* } } + + pub fn is_inlined(name: Atom, arity: usize) -> bool { + match (name, arity) { + #( + #is_inlined_arms, + )* + _ => false, + } + } } #[derive(Clone, Debug)] @@ -3134,15 +3172,6 @@ pub fn generate_instructions_rs() -> TokenStream { } } - pub fn perm_vars_mut(&mut self) -> Option<&mut usize> { - match self { - #( - #perm_vars_mut_arms, - )* - _ => None, - } - } - pub fn is_ctrl_instr(&self) -> bool { match self { &Instruction::Allocate(_) | @@ -3205,41 +3234,6 @@ fn is_jmp(id: &Ident) -> bool { } fn create_instr_variant(id: Ident, mut variant: Variant) -> Variant { - use proc_macro2::Span; - use syn::punctuated::Punctuated; - use syn::token::Paren; - - // add the perm_vars usize field to the variant. - - if is_callable(&id) || is_jmp(&id) { - let field = Field { - attrs: vec![], - vis: Visibility::Inherited, - ident: None, - colon_token: None, - ty: parse_quote! { usize }, - }; - - match &mut variant.fields { - Fields::Unnamed(ref mut fields) => { - fields.unnamed.push(field); - } - Fields::Unit => { - variant.fields = Fields::Unnamed(FieldsUnnamed { - paren_token: Paren(Span::call_site()), - unnamed: { - let mut fields_seq = Punctuated::new(); - fields_seq.push(field); - fields_seq - } - }); - } - _ => { - unreachable!(); - } - } - } - variant.ident = id; variant.attrs.clear(); diff --git a/src/allocator.rs b/src/allocator.rs index 5be3aae1..f689a802 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,14 +1,10 @@ use crate::parser::ast::*; -use crate::temp_v; -use crate::fixtures::*; use crate::forms::*; use crate::instructions::*; -use crate::machine::machine_indices::*; use crate::targets::*; use std::cell::Cell; -use std::rc::Rc; pub(crate) trait Allocator { fn new() -> Self; @@ -17,7 +13,7 @@ pub(crate) trait Allocator { &mut self, lvl: Level, context: GenContext, - code: &mut Code, + code: &mut CodeDeque, ); fn mark_non_var<'a, Target: CompilationTarget<'a>>( @@ -25,83 +21,71 @@ pub(crate) trait Allocator { lvl: Level, context: GenContext, cell: &'a Cell, - code: &mut Code, + code: &mut CodeDeque, ); fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( &mut self, - var_name: Rc, + var_num: usize, lvl: Level, cell: &'a Cell, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, r: RegType, is_new_var: bool, ); + fn mark_cut_var(&mut self, var_num: usize, chunk_num: usize) -> RegType; + fn mark_var<'a, Target: CompilationTarget<'a>>( &mut self, - var_name: Rc, + var_num: usize, lvl: Level, cell: &'a Cell, context: GenContext, - code: &mut Code, + code: &mut CodeDeque, ); fn reset(&mut self); - fn reset_contents(&mut self) {} fn reset_arg(&mut self, arg_num: usize); fn reset_at_head(&mut self, args: &Vec); + fn reset_contents(&mut self); fn advance_arg(&mut self); + /* fn bindings(&self) -> &AllocVarDict; fn bindings_mut(&mut self) -> &mut AllocVarDict; - fn take_bindings(self) -> AllocVarDict; + */ + fn max_reg_allocated(&self) -> usize; + // TODO: wha.. why?? grrr. it drains the VarStatus data from vs (which it owns!) + // into self.bindings and perm_vs after all is computed (i.e. vs.populate_restricting_sets() + // and vs.set_perm_vals(has_deep_cut) have both been called). + /* fn drain_var_data<'a>( &mut self, - vs: VariableFixtures<'a>, + vs: VariableFixtures, num_of_chunks: usize, - ) -> VariableFixtures<'a> { + ) -> VariableFixtures { let mut perm_vs = VariableFixtures::new(); - for (var, (var_status, cells)) in vs.into_iter() { + for (var, var_status) in vs.into_iter() { match var_status { VarStatus::Temp(chunk_num, tvd) => { self.bindings_mut() - .insert(var.clone(), VarData::Temp(chunk_num, 0, tvd)); - - if chunk_num + 1 == num_of_chunks { - perm_vs.insert_last_chunk_temp_var(var); - } + .insert(var.clone(), VarAlloc::Temp(chunk_num, 0, tvd)); } VarStatus::Perm(_) => { - self.bindings_mut().insert(var.clone(), VarData::Perm(0)); - perm_vs.insert(var, (var_status, cells)); + self.bindings_mut().insert(var.clone(), VarAlloc::Perm(0)); + perm_vs.insert(var, var_status); } }; } perm_vs } - - fn get(&self, var: Rc) -> RegType { - self.bindings() - .get(&var) - .map_or(temp_v!(0), |v| v.as_reg_type()) - } - - fn is_unbound(&self, var: Rc) -> bool { - self.get(var).reg_num() == 0 - } - - fn record_register(&mut self, var: Rc, r: RegType) { - match self.bindings_mut().get_mut(&var).unwrap() { - &mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(), - &mut VarData::Perm(ref mut s) => *s = r.reg_num(), - } - } + */ } diff --git a/src/arithmetic.rs b/src/arithmetic.rs index 0cbb1eab..0fbd91d5 100644 --- a/src/arithmetic.rs +++ b/src/arithmetic.rs @@ -22,7 +22,6 @@ use std::convert::TryFrom; use std::f64; use std::num::FpCategory; use std::ops::Div; -use std::rc::Rc; use std::vec::Vec; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -53,7 +52,7 @@ pub(crate) struct ArithInstructionIterator<'a> { state_stack: Vec>, } -pub(crate) type ArithCont = (Code, Option); +pub(crate) type ArithCont = (CodeDeque, Option); impl<'a> ArithInstructionIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { @@ -74,7 +73,7 @@ impl<'a> ArithInstructionIterator<'a> { 2, )) } - Term::Var(cell, var) => TermIterState::Var(Level::Shallow, cell, var.clone()), + Term::Var(cell, var_ptr) => TermIterState::Var(Level::Shallow, cell, var_ptr.clone()), }; Ok(ArithInstructionIterator { @@ -87,7 +86,7 @@ impl<'a> ArithInstructionIterator<'a> { pub(crate) enum ArithTermRef<'a> { Literal(&'a Literal), Op(Atom, usize), // name, arity. - Var(Level, &'a Cell, Rc), + Var(Level, &'a Cell, VarPtr), } impl<'a> Iterator for ArithInstructionIterator<'a> { @@ -115,8 +114,8 @@ impl<'a> Iterator for ArithInstructionIterator<'a> { } } TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))), - TermIterState::Var(lvl, cell, var) => { - return Some(Ok(ArithTermRef::Var(lvl, cell, var.clone()))); + TermIterState::Var(lvl, cell, var_ptr) => { + return Some(Ok(ArithTermRef::Var(lvl, cell, var_ptr))); } _ => { return Some(Err(ArithmeticError::NonEvaluableFunctor( @@ -308,43 +307,48 @@ impl<'a> ArithmeticEvaluator<'a> { term_loc: GenContext, arg: usize, ) -> Result { - let mut code = vec![]; + let mut code = CodeDeque::new(); let mut iter = src.iter()?; while let Some(term_ref) = iter.next() { match term_ref? { ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?, ArithTermRef::Var(lvl, cell, name) => { + let var_num = name.to_var_num().unwrap(); + let r = if lvl == Level::Shallow { self.marker.mark_non_callable( - name.clone(), + var_num, arg, term_loc, cell, &mut code, ) } else if term_loc.is_last() || cell.get().norm().reg_num() == 0 { - if let Some(r) = self.marker.get_binding(&name) { - r - } else { + let r = self.marker.get_binding(var_num); + + if r.reg_num() == 0 { self.marker.mark_var::( - name.clone(), + var_num, lvl, cell, term_loc, &mut code, ); - - self.marker.get_binding(&name).unwrap() + } else { + self.marker.increment_running_count(var_num); } + + r } else { + self.marker.increment_running_count(var_num); cell.get().norm() }; self.interm.push(ArithmeticTerm::Reg(r)); } ArithTermRef::Op(name, arity) => { - code.push(self.instr_from_clause(name, arity)?); + code.push_back(self.instr_from_clause(name, arity)?); } } } diff --git a/src/codegen.rs b/src/codegen.rs index 1aea58d2..33ac87d9 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,11 +1,9 @@ use crate::atom_table::*; use crate::parser::ast::*; -use crate::{perm_v, temp_v}; - +use crate::temp_v; use crate::allocator::*; use crate::arithmetic::*; use crate::debray_allocator::*; -use crate::fixtures::*; use crate::forms::*; use crate::indexing::*; use crate::instructions::*; @@ -14,40 +12,129 @@ use crate::targets::*; use crate::types::*; use crate::instr; +use crate::machine::disjuncts::*; use crate::machine::machine_errors::*; -use indexmap::{IndexMap, IndexSet}; +use fxhash::FxBuildHasher; +use indexmap::IndexSet; use std::cell::Cell; use std::collections::VecDeque; -use std::rc::Rc; #[derive(Debug)] -pub(crate) struct ConjunctInfo<'a> { - pub(crate) perm_vs: VariableFixtures<'a>, - pub(crate) num_of_chunks: usize, - pub(crate) has_deep_cut: bool, +pub struct BranchCodeStack { + pub stack: Vec>, } -impl<'a> ConjunctInfo<'a> { - fn new(perm_vs: VariableFixtures<'a>, num_of_chunks: usize, has_deep_cut: bool) -> Self { - ConjunctInfo { - perm_vs, - num_of_chunks, - has_deep_cut, +pub type SubsumedBranchHits = IndexSet; + +impl BranchCodeStack { + fn new() -> Self { + Self { stack: vec![] } + } + + fn add_new_branch_stack(&mut self) { + self.stack.push(vec![]); + } + + fn add_new_branch(&mut self) { + if self.stack.is_empty() { + self.add_new_branch_stack(); + } + + if let Some(branches) = self.stack.last_mut() { + branches.push(CodeDeque::new()); } } - fn allocates(&self) -> bool { - self.perm_vs.size() > 0 || self.num_of_chunks > 1 || self.has_deep_cut + fn code<'a>(&'a mut self, default_code: &'a mut CodeDeque) -> &'a mut CodeDeque { + self.stack.last_mut() + .and_then(|stack| stack.last_mut()) + .unwrap_or(default_code) } - fn perm_vars(&self) -> usize { - self.perm_vs.size() + self.perm_var_offset() + fn push_missing_vars(&mut self, depth: usize, marker: &mut DebrayAllocator) -> SubsumedBranchHits { + let mut subsumed_hits = SubsumedBranchHits::with_hasher(FxBuildHasher::default()); + + for idx in (self.stack.len() - depth .. self.stack.len()).rev() { + let branch = &mut marker.branch_stack[idx]; + let branch_hits = &branch.hits; + + for (&var_num, branches) in branch_hits.iter() { + let record = &marker.var_data.records[var_num]; + + if record.running_count < record.num_occurrences { + if !branches.all() { + branch.deep_safety.insert(var_num); + branch.shallow_safety.insert(var_num); + + let r = record.allocation.as_reg_type(); + + // iterate over unset bits. + for branch_idx in branches.iter_zeros() { + if branch_idx + 1 == branches.len() && idx + 1 != self.stack.len() { + break; + } + + self.stack[idx][branch_idx].push_back(instr!("put_variable", r, 0)); + } + } + + subsumed_hits.insert(var_num); + } + } + } + + subsumed_hits } - fn perm_var_offset(&self) -> usize { - self.has_deep_cut as usize + fn push_jump_instrs(&mut self, depth: usize) { + // add 2 in each arm length to compensate for each jump + // instruction and each branch instruction not yet added. + let mut jump_span: usize = self.stack[self.stack.len() - depth ..] + .iter() + .map(|branch| branch.iter().map(|code| code.len() + 2).sum::()) + .sum(); + + jump_span -= depth; + + for idx in self.stack.len() - depth .. self.stack.len() { + let inner_len = self.stack[idx].len(); + + for (inner_idx, code) in self.stack[idx].iter_mut().enumerate() { + if inner_idx + 1 == inner_len { + jump_span -= code.len() + 1; + } else { + jump_span -= code.len() + 1; + code.push_back(instr!("jmp_by_call", jump_span as usize)); + + jump_span -= 1; + } + } + } + } + + fn pop_branch(&mut self, depth: usize, settings: CodeGenSettings) -> CodeDeque { + let mut combined_code = CodeDeque::new(); + + for mut branch_arm in self.stack.drain(self.stack.len() - depth ..).rev() { + let num_branch_arms = branch_arm.len(); + branch_arm.last_mut().map(|code| code.extend(combined_code.drain(..))); + + for (idx, code) in branch_arm.into_iter().enumerate() { + combined_code.push_back(if idx == 0 { + Instruction::TryMeElse(code.len() + 1) + } else if idx + 1 < num_branch_arms { + settings.retry_me_else(code.len() + 1) + } else { + settings.trust_me() + }); + + combined_code.extend(code.into_iter()); + } + } + + combined_code } } @@ -170,53 +257,49 @@ impl CodeGenSettings { pub(crate) struct CodeGenerator<'a> { pub(crate) atom_tbl: &'a mut AtomTable, marker: DebrayAllocator, - pub(crate) var_count: IndexMap, usize>, settings: CodeGenSettings, pub(crate) skeleton: PredicateSkeleton, - pub(crate) jmp_by_locs: Vec, - global_jmp_by_locs_offset: usize, } impl DebrayAllocator { fn mark_var_in_non_callable( &mut self, - name: Rc, + var_num: usize, term_loc: GenContext, vr: &Cell, - code: &mut Code, + code: &mut CodeDeque, ) -> RegType { - self.mark_var::(name, Level::Shallow, vr, term_loc, code); - vr.get().norm() - } + self.mark_var::( + var_num, + Level::Shallow, + vr, + term_loc, + code, + ); - #[inline(always)] - pub(crate) fn get_binding(&self, name: &String) -> Option { - match self.bindings().get(name) { - Some(&VarData::Temp(_, t, _)) if t != 0 => Some(RegType::Temp(t)), - Some(&VarData::Perm(p)) if p != 0 => Some(RegType::Perm(p)), - _ => None, - } + vr.get().norm() } pub(crate) fn mark_non_callable( &mut self, - name: Rc, + var_num: usize, arg: usize, term_loc: GenContext, vr: &Cell, - code: &mut Code, + code: &mut CodeDeque, ) -> RegType { - match self.get_binding(&name) { - Some(RegType::Temp(t)) => RegType::Temp(t), - Some(RegType::Perm(p)) => { + match self.get_binding(var_num) { + RegType::Temp(t) if t != 0 => RegType::Temp(t), + RegType::Perm(p) if p != 0 => { if let GenContext::Last(_) = term_loc { - self.mark_var_in_non_callable(name.clone(), term_loc, vr, code); + self.mark_var_in_non_callable(var_num, term_loc, vr, code); temp_v!(arg) } else { + self.increment_running_count(var_num); RegType::Perm(p) } } - None => self.mark_var_in_non_callable(name, term_loc, vr, code), + _ => self.mark_var_in_non_callable(var_num, term_loc, vr, code), } } } @@ -249,7 +332,7 @@ trait AddToFreeList<'a, Target: CompilationTarget<'a>> { impl<'a, 'b> AddToFreeList<'a, FactInstruction> for CodeGenerator<'b> { fn add_term_to_free_list(&mut self, r: RegType) { - self.marker.add_to_free_list(r); + self.marker.add_reg_to_free_list(r); } fn add_subterm_to_free_list(&mut self, _term: &Term) {} @@ -262,7 +345,7 @@ impl<'a, 'b> AddToFreeList<'a, QueryInstruction> for CodeGenerator<'b> { #[inline(always)] fn add_subterm_to_free_list(&mut self, term: &Term) { if let Some(cell) = structure_cell(term) { - self.marker.add_to_free_list(cell.get()); + self.marker.add_reg_to_free_list(cell.get()); } } } @@ -282,50 +365,34 @@ impl<'b> CodeGenerator<'b> { CodeGenerator { atom_tbl, marker: DebrayAllocator::new(), - var_count: IndexMap::new(), settings, skeleton: PredicateSkeleton::new(), - jmp_by_locs: vec![], - global_jmp_by_locs_offset: 0, } } - fn update_var_count<'a, Iter: Iterator>>(&mut self, iter: Iter) { - for term in iter { - if let TermRef::Var(_, _, var) = term { - let entry = self.var_count.entry(var).or_insert(0); - *entry += 1; - } - } - } - - fn get_var_count(&self, var: &String) -> usize { - *self.var_count.get(var).unwrap() - } - - fn add_or_increment_void_instr<'a, Target>(target: &mut Code) + fn add_or_increment_void_instr<'a, Target>(target: &mut CodeDeque) where Target: crate::targets::CompilationTarget<'a>, { - if let Some(ref mut instr) = target.last_mut() { + if let Some(ref mut instr) = target.back_mut() { if Target::is_void_instr(&*instr) { Target::incr_void_instr(instr); return; } } - target.push(Target::to_void(1)); + target.push_back(Target::to_void(1)); } fn deep_var_instr<'a, Target: crate::targets::CompilationTarget<'a>>( &mut self, cell: &'a Cell, - var: &Rc, + var_num: usize, term_loc: GenContext, - target: &mut Code, + target: &mut CodeDeque, ) { - if self.get_var_count(var.as_ref()) > 1 { - self.marker.mark_var::(var.clone(), Level::Deep, cell, term_loc, target); + if self.marker.var_data.records[var_num].num_occurrences > 1 { + self.marker.mark_var::(var_num, Level::Deep, cell, term_loc, target); } else { Self::add_or_increment_void_instr::(target); } @@ -335,7 +402,7 @@ impl<'b> CodeGenerator<'b> { &mut self, subterm: &'a Term, term_loc: GenContext, - target: &mut Code, + target: &mut CodeDeque, ) { match subterm { &Term::AnonVar => { @@ -346,13 +413,13 @@ impl<'b> CodeGenerator<'b> { Term::PartialString(ref cell, ..) | Term::CompleteString(ref cell, ..) => { self.marker.mark_non_var::(Level::Deep, term_loc, cell, target); - target.push(Target::clause_arg_to_instr(cell.get())); + target.push_back(Target::clause_arg_to_instr(cell.get())); } &Term::Literal(_, ref constant) => { - target.push(Target::constant_subterm(constant.clone())); + target.push_back(Target::constant_subterm(constant.clone())); } - &Term::Var(ref cell, ref var) => { - self.deep_var_instr::(cell, var, term_loc, target); + &Term::Var(ref cell, ref var_ptr) => { + self.deep_var_instr::(cell, var_ptr.to_var_num().unwrap(), term_loc, target); } }; } @@ -361,13 +428,13 @@ impl<'b> CodeGenerator<'b> { &mut self, iter: Iter, term_loc: GenContext, - ) -> Code + ) -> CodeDeque where Target: crate::targets::CompilationTarget<'a>, Iter: Iterator>, CodeGenerator<'b>: AddToFreeList<'a, Target> { - let mut target: Code = Vec::new(); + let mut target = CodeDeque::new(); for term in iter { match term { @@ -380,11 +447,11 @@ impl<'b> CodeGenerator<'b> { } TermRef::Clause(lvl, cell, name, terms) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_structure(name, terms.len(), cell.get())); + target.push_back(Target::to_structure(name, terms.len(), cell.get())); as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get()); - if let Some(instr) = target.last_mut() { + if let Some(instr) = target.back_mut() { if let Some(term) = terms.last() { trim_structure_by_last_arg(instr, term); } @@ -400,7 +467,7 @@ impl<'b> CodeGenerator<'b> { } TermRef::Cons(lvl, cell, head, tail) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_list(lvl, cell.get())); + target.push_back(Target::to_list(lvl, cell.get())); as AddToFreeList<'a, Target>>::add_term_to_free_list(self, cell.get()); @@ -412,44 +479,31 @@ impl<'b> CodeGenerator<'b> { } TermRef::Literal(lvl @ Level::Shallow, cell, Literal::String(ref string)) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_pstr(lvl, *string, cell.get(), false)); + target.push_back(Target::to_pstr(lvl, *string, cell.get(), false)); } TermRef::Literal(lvl @ Level::Shallow, cell, constant) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_constant(lvl, *constant, cell.get())); + target.push_back(Target::to_constant(lvl, *constant, cell.get())); } TermRef::PartialString(lvl, cell, string, tail) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); let atom = self.atom_tbl.build_with(&string); - target.push(Target::to_pstr(lvl, atom, cell.get(), true)); + target.push_back(Target::to_pstr(lvl, atom, cell.get(), true)); self.subterm_to_instr::(tail, term_loc, &mut target); } TermRef::CompleteString(lvl, cell, atom) => { self.marker.mark_non_var::(lvl, term_loc, cell, &mut target); - target.push(Target::to_pstr(lvl, atom, cell.get(), false)); - } - TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => { - if self.marker.is_unbound(var.clone()) { - if term_loc != GenContext::Head { - self.marker.mark_reserved_var::( - var.clone(), - lvl, - cell, - term_loc, - &mut target, - perm_v!(1), - false, - ); - - continue; - } - } - - self.marker.mark_var::(var.clone(), lvl, cell, term_loc, &mut target); + target.push_back(Target::to_pstr(lvl, atom, cell.get(), false)); } TermRef::Var(lvl @ Level::Shallow, cell, var) => { - self.marker.mark_var::(var.clone(), lvl, cell, term_loc, &mut target); + self.marker.mark_var::( + var.to_var_num().unwrap(), + lvl, + cell, + term_loc, + &mut target, + ); } _ => {} }; @@ -458,80 +512,27 @@ impl<'b> CodeGenerator<'b> { target } - fn collect_var_data<'a>(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> { - let mut vs = VariableFixtures::new(); - - while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() { - for (i, chunked_term) in chunked_terms.iter().enumerate() { - let term_loc = match chunked_term { - &ChunkedTerm::HeadClause(..) => GenContext::Head, - &ChunkedTerm::BodyTerm(_) => { - if i < chunked_terms.len() - 1 { - GenContext::Mid(chunk_num) - } else { - GenContext::Last(chunk_num) - } - } - }; - - self.update_var_count(chunked_term.post_order_iter()); - vs.mark_vars_in_chunk(chunked_term.post_order_iter(), lt_arity, term_loc); - } + fn add_call(&mut self, code: &mut CodeDeque, call_instr: Instruction, call_policy: CallPolicy) { + if self.marker.in_tail_position && self.marker.var_data.allocates { + code.push_back(instr!("deallocate")); } - let num_of_chunks = iter.chunk_num; - let has_deep_cut = iter.encountered_deep_cut(); - - vs.populate_restricting_sets(); - vs.set_perm_vals(has_deep_cut); - - let vs = self.marker.drain_var_data(vs, num_of_chunks); - ConjunctInfo::new(vs, num_of_chunks, has_deep_cut) - } - - fn add_conditional_call(&mut self, code: &mut Code, qt: &QueryTerm, pvs: usize) { - match qt { - &QueryTerm::Jump(ref vars) => { - self.jmp_by_locs.push(code.len()); - code.push(instr!("jmp_by_call", vars.len(), 0, pvs)); - } - &QueryTerm::Clause(_, ref ct, _, CallPolicy::Default) => { - code.push(call_clause_by_default!(ct.clone(), pvs)); - } - &QueryTerm::Clause(_, ref ct, _, CallPolicy::Counted) => { - code.push(call_clause!(ct.clone(), pvs)); - } - _ => {} - } - } - - fn lco(code: &mut Code) -> usize { - let mut dealloc_index = code.len() - 1; - let last_instr = code.pop(); - - match last_instr { - Some(instr @ Instruction::Proceed) => { - code.push(instr); - } - Some(instr @ Instruction::Cut(_)) => { - dealloc_index += 1; - code.push(instr); - } - Some(mut instr) if instr.is_ctrl_instr() => { - code.push(if instr.perm_vars_mut().is_some() { - instr.to_execute() + match call_policy { + CallPolicy::Default => { + if self.marker.in_tail_position { + code.push_back(call_instr.to_execute().to_default()); } else { - dealloc_index += 1; - instr - }); + code.push_back(call_instr.to_default()) + } } - Some(instr) => { - code.push(instr); + CallPolicy::Counted => { + if self.marker.in_tail_position { + code.push_back(call_instr.to_execute()); + } else { + code.push_back(call_instr) + } } - None => {} } - - dealloc_index } fn compile_inlined<'a>( @@ -539,9 +540,9 @@ impl<'b> CodeGenerator<'b> { ct: &InlinedClauseType, terms: &'a Vec, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, ) -> Result<(), CompilationError> { - match ct { + let call_instr = match ct { &InlinedClauseType::CompareNumber(mut cmp) => { self.marker.reset_arg(2); @@ -559,29 +560,29 @@ impl<'b> CodeGenerator<'b> { let at_1 = at_1.unwrap_or(interm!(1)); let at_2 = at_2.unwrap_or(interm!(2)); - code.push(compare_number_instr!(cmp, at_1, at_2)); + compare_number_instr!(cmp, at_1, at_2) } &InlinedClauseType::IsAtom(..) => match &terms[0] { &Term::Literal(_, Literal::Char(_)) | &Term::Literal(_, Literal::Atom(atom!("[]"))) | &Term::Literal(_, Literal::Atom(..)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("atom", r, 0)); + instr!("atom", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsAtomic(..) => match &terms[0] { @@ -590,26 +591,26 @@ impl<'b> CodeGenerator<'b> { &Term::Cons(..) | &Term::PartialString(..) | &Term::CompleteString(..) => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::Literal(_, Literal::String(_)) => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::Literal(..) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("atomic", r, 0)); + instr!("atomic", r) } }, &InlinedClauseType::IsCompound(..) => match &terms[0] { @@ -618,57 +619,57 @@ impl<'b> CodeGenerator<'b> { &Term::PartialString(..) | &Term::CompleteString(..) | &Term::Literal(_, Literal::String(..)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("compound", r, 0)); + instr!("compound", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsRational(..) => match &terms[0] { &Term::Literal(_, Literal::Rational(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); - let r = self.marker.mark_non_callable(name.clone(), 1, term_loc, vr, code); - code.push(instr!("rational", r, 0)); + let r = self.marker.mark_non_callable(name.to_var_num().unwrap(), 1, term_loc, vr, code); + instr!("rational", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsFloat(..) => match &terms[0] { &Term::Literal(_, Literal::Float(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("float", r, 0)); + instr!("float", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsNumber(..) => match &terms[0] { @@ -676,66 +677,66 @@ impl<'b> CodeGenerator<'b> { &Term::Literal(_, Literal::Rational(_)) | &Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("number", r, 0)); + instr!("number", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsNonVar(..) => match &terms[0] { &Term::AnonVar => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("nonvar", r, 0)); + instr!("nonvar", r) } _ => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } }, &InlinedClauseType::IsInteger(..) => match &terms[0] { &Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("integer", r, 0)); + instr!("integer", r) } _ => { - code.push(instr!("$fail", 0)); + instr!("$fail") } }, &InlinedClauseType::IsVar(..) => match &terms[0] { @@ -744,26 +745,29 @@ impl<'b> CodeGenerator<'b> { &Term::Cons(..) | &Term::PartialString(..) | &Term::CompleteString(..) => { - code.push(instr!("$fail", 0)); + instr!("$fail") } &Term::AnonVar => { - code.push(instr!("$succeed", 0)); + instr!("$succeed") } &Term::Var(ref vr, ref name) => { self.marker.reset_arg(1); let r = self.marker.mark_non_callable( - name.clone(), + name.to_var_num().unwrap(), 1, term_loc, vr, code, ); - code.push(instr!("var", r, 0)); + instr!("var", r) } }, - } + }; + + // inlined predicates are never counted, so this overrides nothing. + self.add_call(code, call_instr, CallPolicy::Counted); Ok(()) } @@ -782,7 +786,7 @@ impl<'b> CodeGenerator<'b> { fn compile_is_call( &mut self, terms: &Vec, - code: &mut Code, + code: &mut CodeDeque, term_loc: GenContext, call_policy: CallPolicy, ) -> Result<(), CompilationError> { @@ -798,14 +802,18 @@ impl<'b> CodeGenerator<'b> { let at = match &terms[0] { &Term::Var(ref vr, ref name) => { + let var_num = name.to_var_num().unwrap(); + self.marker.mark_var::( - name.clone(), + var_num, Level::Shallow, vr, term_loc, code, ); + self.marker.mark_safe_var_unconditionally(var_num); + compile_expr!(self, &terms[1], term_loc, code) } &Term::Literal(_, c @ Literal::Integer(_) | @@ -813,227 +821,189 @@ impl<'b> CodeGenerator<'b> { c @ Literal::Rational(_) | c @ Literal::Fixnum(_)) => { let v = HeapCellValue::from(c); - code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1))); + code.push_back(instr!("put_constant", Level::Shallow, v, temp_v!(1))); self.marker.advance_arg(); compile_expr!(self, &terms[1], term_loc, code) } _ => { - code.push(instr!("$fail", 0)); + code.push_back(instr!("$fail")); return Ok(()); } }; let at = at.unwrap_or(interm!(1)); + self.add_call(code, instr!("is", temp_v!(1), at), call_policy); - Ok(if let CallPolicy::Default = call_policy { - code.push(instr!("is", default, temp_v!(1), at, 0)); - } else { - code.push(instr!("is", temp_v!(1), at, 0)); - }) - } - - #[inline] - fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &Cell) { - let r = self.marker.get(Rc::new(String::from("!"))); - cell.set(VarReg::Norm(r)); - code.push(instr!("$set_cp", cell.get().norm(), 0)); - } - - fn compile_get_level_and_unify( - &mut self, - code: &mut Code, - cell: &Cell, - var: Rc, - term_loc: GenContext, - ) { - let mut target = Code::new(); - - self.marker.reset_arg(1); - self.marker.mark_var::(var, Level::Shallow, cell, term_loc, &mut target); - - if !target.is_empty() { - code.extend(target.into_iter()); - } - - code.push(instr!("get_level_and_unify", cell.get().norm())); + Ok(()) } fn compile_seq<'a>( &mut self, - iter: ChunkedIterator<'a>, - conjunct_info: &ConjunctInfo<'a>, - code: &mut Code, + clauses: &ChunkedTermVec, + code: &mut CodeDeque, ) -> Result<(), CompilationError> { - for (chunk_num, _, terms) in iter.rule_body_iter() { - for (i, term) in terms.iter().enumerate() { - let term_loc = if i + 1 < terms.len() { - GenContext::Mid(chunk_num) - } else { - GenContext::Last(chunk_num) - }; + let mut chunk_num = 0; + let mut branch_code_stack = BranchCodeStack::new(); + let mut clause_iter = ClauseIterator::new(clauses); - match *term { - &QueryTerm::GetLevelAndUnify(ref cell, ref var) => { - self.compile_get_level_and_unify(code, cell, var.clone(), term_loc) - } - &QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell), - &QueryTerm::BlockedCut => code.push(if chunk_num == 0 { - Instruction::NeckCut - } else { - Instruction::Cut(perm_v!(1)) - }), - &QueryTerm::Clause( - _, - ClauseType::BuiltIn(BuiltInClauseType::Is(..)), - ref terms, - call_policy, - ) => self.compile_is_call(terms, code, term_loc, call_policy)?, - &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { - self.compile_inlined(ct, terms, term_loc, code)? - } - _ => { - let num_perm_vars = if chunk_num == 0 { - conjunct_info.perm_vars() + while let Some(clause_item) = clause_iter.next() { + match clause_item { + ClauseItem::Chunk(chunk) => { + for (idx, term) in chunk.iter().enumerate() { + let term_loc = if idx + 1 < chunk.len() { + GenContext::Mid(chunk_num) } else { - conjunct_info.perm_vs.vars_above_threshold(i + 1) + self.marker.in_tail_position = clause_iter.in_tail_position(); + GenContext::Last(chunk_num) }; - self.compile_query_line(term, term_loc, code, num_perm_vars); + match term { + &QueryTerm::GetLevel(var_num) => { + let code = branch_code_stack.code(code); + let r = self.marker.mark_cut_var(var_num, chunk_num); + code.push_back(instr!("get_level", r)); + } + &QueryTerm::GetCutPoint { var_num, prev_b } => { + let code = branch_code_stack.code(code); + let r = self.marker.mark_cut_var(var_num, chunk_num); - if self.marker.max_reg_allocated() > MAX_ARITY { - return Err(CompilationError::ExceededMaxArity); + code.push_back(if prev_b { + instr!("get_prev_level", r) + } else { + instr!("get_cut_point", r) + }); + } + &QueryTerm::GlobalCut(var_num) => { + let code = branch_code_stack.code(code); + + if chunk_num == 0 { + code.push_back(instr!("neck_cut")); + } else { + let r = self.marker.get_binding(var_num); + code.push_back(instr!("cut", r)); + } + + if self.marker.in_tail_position { + if self.marker.var_data.allocates { + code.push_back(instr!("deallocate")); + } + + code.push_back(instr!("proceed")); + } + } + &QueryTerm::LocalCut(var_num) => { + let code = branch_code_stack.code(code); + let r = self.marker.get_binding(var_num); + code.push_back(instr!("cut", r)); + + if self.marker.in_tail_position { + if self.marker.var_data.allocates { + code.push_back(instr!("deallocate")); + } + + code.push_back(instr!("proceed")); + } else { + self.marker.free_var(chunk_num, var_num); + } + } + &QueryTerm::Clause( + _, + ClauseType::BuiltIn(BuiltInClauseType::Is(..)), + ref terms, + call_policy, + ) => self.compile_is_call(terms, branch_code_stack.code(code), term_loc, call_policy)?, + &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { + self.compile_inlined(ct, terms, term_loc, branch_code_stack.code(code))? + } + &QueryTerm::Fail => { + branch_code_stack.code(code).push_back(instr!("$fail")); + } + term @ &QueryTerm::Clause(..) => { + self.compile_query_line(term, term_loc, branch_code_stack.code(code)); + + if self.marker.max_reg_allocated() > MAX_ARITY { + return Err(CompilationError::ExceededMaxArity); + } + } } } + + chunk_num += 1; + self.marker.in_tail_position = false; + self.marker.reset_contents(); + } + ClauseItem::FirstBranch(num_branches) => { + branch_code_stack.add_new_branch_stack(); + branch_code_stack.add_new_branch(); + + self.marker.add_branch_stack(num_branches); + self.marker.add_branch(); + } + ClauseItem::NextBranch => { + branch_code_stack.add_new_branch(); + self.marker.add_branch(); + self.marker.incr_current_branch(); + } + ClauseItem::BranchEnd(depth) => { + if !clause_iter.in_tail_position() { + let subsumed_hits = branch_code_stack.push_missing_vars(depth, &mut self.marker); + self.marker.pop_branch(depth, subsumed_hits); + branch_code_stack.push_jump_instrs(depth); + } else { + self.marker.drain_branches(depth); + } + + let settings = CodeGenSettings { + non_counted_bt: self.settings.non_counted_bt, + is_extensible: false, + global_clock_tick: None, + }; + + let branch_code = branch_code_stack.pop_branch(depth, settings); + branch_code_stack.code(code).extend(branch_code); } } + } - self.marker.reset_contents(); + if self.marker.var_data.allocates { + code.push_front(instr!("allocate", self.marker.num_perm_vars())); } Ok(()) } - fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) { - if conjunct_info.allocates() { - let perm_vars = conjunct_info.perm_vars(); - - body.push(Instruction::Allocate(perm_vars)); - - if conjunct_info.has_deep_cut { - body.push(Instruction::GetLevel(perm_v!(1))); - } - } - } - - fn compile_cleanup<'a>( - &mut self, - code: &mut Code, - conjunct_info: &ConjunctInfo<'a>, - toc: &'a QueryTerm, - ) { - // add a proceed to bookend any trailing cuts. - match toc { - &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => { - code.push(instr!("proceed")); - } - _ => {} - }; - - // perform lco. - let dealloc_index = Self::lco(code); - - if conjunct_info.allocates() { - let offset = self.global_jmp_by_locs_offset; - - if let Some(jmp_by_offset) = self.jmp_by_locs[offset..].last_mut() { - if *jmp_by_offset == dealloc_index { - *jmp_by_offset += 1; - } - } - - code.insert(dealloc_index, instr!("deallocate")); - } - } - - pub(crate) fn compile_rule(&mut self, rule: &Rule) -> Result { - let iter = ChunkedIterator::from_rule(rule); - let conjunct_info = self.collect_var_data(iter); - - let &Rule { - head: (_, ref args, ref p1), - ref clauses, - } = rule; - - let mut code = Code::new(); + pub(crate) fn compile_rule(&mut self, rule: &Rule, var_data: VarData) -> Result { + let Rule { head: (_, args), clauses } = rule; + self.marker.var_data = var_data; + let mut code = VecDeque::new(); self.marker.reset_at_head(args); - self.compile_seq_prelude(&conjunct_info, &mut code); - let iter = FactIterator::from_rule_head_clause(args); - let mut fact = self.compile_target::(iter, GenContext::Head); + let iter = FactIterator::from_rule_head_clause(&args); + let fact = self.compile_target::(iter, GenContext::Head); if self.marker.max_reg_allocated() > MAX_ARITY { return Err(CompilationError::ExceededMaxArity); } self.marker.reset_free_list(); + code.extend(fact.into_iter()); - let mut unsafe_var_marker = UnsafeVarMarker::new(); + self.compile_seq(clauses, &mut code)?; - if !fact.is_empty() { - unsafe_var_marker = self.mark_unsafe_fact_vars(&mut fact); - code.extend(fact.into_iter()); - } - - let iter = ChunkedIterator::from_rule_body(p1, clauses); - self.compile_seq(iter, &conjunct_info, &mut code)?; - - unsafe_var_marker.mark_unsafe_instrs(&mut code); - - self.compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1)); - - Ok(code) + Ok(Vec::from(code)) } - fn mark_unsafe_fact_vars(&self, fact: &mut Code) -> UnsafeVarMarker { - let mut safe_vars = IndexSet::new(); - - for fact_instr in fact.iter_mut() { - match fact_instr { - &mut Instruction::UnifyValue(r) => { - if !safe_vars.contains(&r) { - *fact_instr = Instruction::UnifyLocalValue(r); - safe_vars.insert(r); - } - } - &mut Instruction::UnifyVariable(r) => { - safe_vars.insert(r); - } - _ => {} - } - } - - UnsafeVarMarker::from_fact_vars(safe_vars) - } - - pub(crate) fn compile_fact(&mut self, term: &Term) -> Result { - self.update_var_count(post_order_iter(term)); - - let mut vs = VariableFixtures::new(); - - vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head); - - vs.populate_restricting_sets(); - self.marker.drain_var_data(vs, 1); - + pub(crate) fn compile_fact(&mut self, fact: &Fact, var_data: VarData) -> Result { let mut code = Vec::new(); + self.marker.var_data = var_data; - if let &Term::Clause(_, _, ref args) = term { + if let Term::Clause(_, _, args) = &fact.head { self.marker.reset_at_head(args); - let iter = FactInstruction::iter(term); - let mut compiled_fact = self.compile_target::( + let iter = FactInstruction::iter(&fact.head); + let compiled_fact = self.compile_target::( iter, GenContext::Head, ); @@ -1042,40 +1012,27 @@ impl<'b> CodeGenerator<'b> { return Err(CompilationError::ExceededMaxArity); } - self.mark_unsafe_fact_vars(&mut compiled_fact); - - if !compiled_fact.is_empty() { - code.extend(compiled_fact.into_iter()); - } + code.extend(compiled_fact.into_iter()); } code.push(instr!("proceed")); Ok(code) } - fn compile_query_line( - &mut self, - term: &QueryTerm, - term_loc: GenContext, - code: &mut Code, - num_perm_vars_left: usize, - ) { + fn compile_query_line(&mut self, term: &QueryTerm, term_loc: GenContext, code: &mut CodeDeque) { self.marker.reset_arg(term.arity()); - let iter = query_term_post_order_iter(term); + let iter = QueryIterator::new(term); let query = self.compile_target::(iter, term_loc); code.extend(query.into_iter()); - self.add_conditional_call(code, term, num_perm_vars_left); - } - #[inline] - fn increment_jmp_by_locs_by(&mut self, incr: usize) { - let offset = self.global_jmp_by_locs_offset; - - for loc in &mut self.jmp_by_locs[offset..] { - *loc += incr; - } + match term { + &QueryTerm::Clause(_, ref ct, _, call_policy) => { + self.add_call(code, ct.to_instr(), call_policy); + } + _ => unreachable!() + }; } fn split_predicate(clauses: &[PredicateClause]) -> Vec { @@ -1140,30 +1097,35 @@ impl<'b> CodeGenerator<'b> { fn compile_pred_subseq( &mut self, - clauses: &[PredicateClause], + clauses: &mut [PredicateClause], optimal_index: usize, ) -> Result { let mut code = VecDeque::new(); let mut code_offsets = CodeOffsets::new(I::new(), optimal_index + 1); let mut skip_stub_try_me_else = false; - let jmp_by_locs_len = self.jmp_by_locs.len(); + let clauses_len = clauses.len(); - for (i, clause) in clauses.iter().enumerate() { + for (i, clause) in clauses.iter_mut().enumerate() { self.marker.reset(); let mut clause_index_info = ClauseIndexInfo::new(code.len()); - self.global_jmp_by_locs_offset = self.jmp_by_locs.len(); let clause_code = match clause { - &PredicateClause::Fact(ref fact, ..) => self.compile_fact(fact)?, - &PredicateClause::Rule(ref rule, ..) => self.compile_rule(rule)?, + PredicateClause::Fact(fact, var_data) => { + let var_data = std::mem::replace(var_data, VarData::default()); + self.compile_fact(&fact, var_data)? + } + PredicateClause::Rule(rule, var_data) => { + let var_data = std::mem::replace(var_data, VarData::default()); + self.compile_rule(&rule, var_data)? + } }; - if clauses.len() > 1 { + if clauses_len > 1 { let choice = match i { 0 => self.settings.internal_try_me_else(clause_code.len() + 1), - _ if i == clauses.len() - 1 => self.settings.internal_trust_me(), + _ if i + 1 == clauses_len => self.settings.internal_trust_me(), _ => self.settings.internal_retry_me_else(clause_code.len() + 1), }; @@ -1189,45 +1151,23 @@ impl<'b> CodeGenerator<'b> { if let Some(arg) = arg { let index = code.len(); - if clauses.len() > 1 || self.settings.is_extensible { + if clauses_len > 1 || self.settings.is_extensible { code_offsets.index_term(arg, index, &mut clause_index_info, self.atom_tbl); } } - if !(code_offsets.no_indices() && clauses.len() == 1 && self.settings.is_extensible) { - // the peculiar condition of this block, when false, - // anticipates code.pop_front() being called about a - // dozen lines below. - - if !skip_stub_try_me_else { - // if the condition is false, code_offsets.no_indices() is false, - // so don't repeat the work of the condition on skip_stub_try_me_else - // below. - self.increment_jmp_by_locs_by(code.len()); - } - } - self.skeleton.clauses.push_back(clause_index_info); code.extend(clause_code.into_iter()); } - let index_code = if clauses.len() > 1 || self.settings.is_extensible { + let index_code = if clauses_len > 1 || self.settings.is_extensible { code_offsets.compute_indices(skip_stub_try_me_else) } else { vec![] }; - self.global_jmp_by_locs_offset = jmp_by_locs_len; - if !index_code.is_empty() { code.push_front(Instruction::IndexingCode(index_code)); - - if skip_stub_try_me_else { - // skip the TryMeElse(0) also. - self.increment_jmp_by_locs_by(2); - } else { - self.increment_jmp_by_locs_by(1); - } } else if clauses.len() == 1 && self.settings.is_extensible { // the condition is the value of skip_stub_try_me_else, which is // true if the predicate is not dynamic. This operation must apply @@ -1242,7 +1182,7 @@ impl<'b> CodeGenerator<'b> { pub(crate) fn compile_predicate( &mut self, - clauses: &Vec, + mut clauses: Vec, ) -> Result { let mut code = Code::new(); @@ -1253,12 +1193,12 @@ impl<'b> CodeGenerator<'b> { let skel_lower_bound = self.skeleton.clauses.len(); let code_segment = if self.settings.is_dynamic() { self.compile_pred_subseq::( - &clauses[left..right], + &mut clauses[left..right], instantiated_arg_index, )? } else { self.compile_pred_subseq::( - &clauses[left..right], + &mut clauses[left..right], instantiated_arg_index, )? }; @@ -1290,9 +1230,6 @@ impl<'b> CodeGenerator<'b> { } } - self.increment_jmp_by_locs_by(code.len()); - self.global_jmp_by_locs_offset = self.jmp_by_locs.len(); - code.extend(code_segment.into_iter()); } diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs index e9cc73c7..c1f32c49 100644 --- a/src/debray_allocator.rs +++ b/src/debray_allocator.rs @@ -1,43 +1,198 @@ -use indexmap::IndexMap; - use crate::allocator::*; -use crate::fixtures::*; +use crate::codegen::SubsumedBranchHits; use crate::forms::Level; use crate::instructions::*; -use crate::machine::machine_indices::*; +use crate::machine::disjuncts::VarData; use crate::parser::ast::*; use crate::targets::*; +use crate::variable_records::*; -use crate::temp_v; - +use bit_set::*; +use bitvec::prelude::*; use fxhash::FxBuildHasher; +use indexmap::IndexMap; use std::cell::Cell; -use std::collections::BTreeSet; -use std::rc::Rc; +use std::collections::VecDeque; + +pub type BranchHits = IndexMap; // key: var_num, value: branch arm occurrences. + +#[derive(Debug, Default)] +pub struct BranchOccurrences { + pub hits: BranchHits, + pub shallow_safety: BitSet, // unset means safe, set means unsafe (after the branch merge) + pub deep_safety: BitSet, + pub num_branches: usize, + pub current_branch: usize, + pub subsumed_hits: SubsumedBranchHits, +} + +impl BranchOccurrences { + fn new(num_branches: usize) -> Self { + Self { + hits: BranchHits::with_hasher(FxBuildHasher::default()), + shallow_safety: BitSet::default(), + deep_safety: BitSet::default(), + num_branches, + current_branch: 0, + subsumed_hits: SubsumedBranchHits::with_hasher(FxBuildHasher::default()), + } + } +} #[derive(Debug)] pub(crate) struct DebrayAllocator { - bindings: IndexMap, VarData, FxBuildHasher>, + pub(crate) var_data: VarData, // var_data replaces bindings. + pub(crate) branch_stack: Vec, + pub(crate) in_tail_position: bool, + // bindings: IndexMap, // VarNum -> VarWitness arg_c: usize, temp_lb: usize, + perm_lb: usize, arity: usize, // 0 if not at head. - contents: IndexMap, FxBuildHasher>, - in_use: BTreeSet, - free_list: Vec, + shallow_temp_mappings: IndexMap, + in_use: BitSet, // deep and non-var allocations + temp_free_list: Vec, + perm_free_list: VecDeque<(usize, usize)>, // chunk_num, var_num } impl DebrayAllocator { - fn is_curr_arg_distinct_from(&self, var: &String) -> bool { - match self.contents.get(&self.arg_c) { - Some(t_var) if **t_var != *var => true, + pub(crate) fn add_branch_occurrence(&mut self, var_num: usize) { + if let Some(occurrences) = self.branch_stack.last_mut() { + debug_assert!(occurrences.current_branch < occurrences.num_branches); + + let num_branches = occurrences.num_branches; + + let entry = occurrences.hits.entry(var_num) + .or_insert_with(|| BitVec::repeat(false, num_branches)); + + entry.set(occurrences.current_branch, true); + occurrences.subsumed_hits.insert(var_num); + } + } + + pub(crate) fn add_branch_stack(&mut self, num_branches: usize) { + self.branch_stack.push(BranchOccurrences::new(num_branches)); + } + + pub(crate) fn current_branch_designator(&self) -> BranchDesignator { + let num_branches = self.branch_stack.len(); + let current_branch = self.branch_stack.last() + .map(|occurrences| occurrences.current_branch) + .unwrap_or(0); + + BranchDesignator((num_branches, current_branch)) + } + + pub(crate) fn add_branch(&mut self) { + let branch_designator = self.current_branch_designator(); + let branch_occurrences = self.branch_stack.last_mut().unwrap(); + + for var_num in branch_occurrences.subsumed_hits.drain(..) { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, ref mut allocation) => { + match allocation { + PermVarAllocation::Done { shallow_safety, deep_safety, .. } => { + if !shallow_safety.is_unneeded(branch_designator) { + branch_occurrences.shallow_safety.insert(var_num); + } + + if !deep_safety.is_unneeded(branch_designator) { + branch_occurrences.deep_safety.insert(var_num); + } + } + _ => { + unreachable!(); + } + } + + *allocation = PermVarAllocation::Pending; + } + _ => unreachable!(), + } + } + } + + #[inline] + pub(crate) fn incr_current_branch(&mut self) { + let branch_occurrences = self.branch_stack.last_mut().unwrap(); + branch_occurrences.current_branch += 1; + } + + #[inline] + pub(crate) fn drain_branches(&mut self, depth: usize) -> std::vec::Drain { + let start_idx = self.branch_stack.len() - depth; + self.branch_stack.drain(start_idx ..) + } + + pub(crate) fn pop_branch(&mut self, depth: usize, subsumed_hits: SubsumedBranchHits) { + let removed_branches = self.drain_branches(depth); + + let (deep_safety, shallow_safety) = removed_branches + .into_iter() + .fold((BitSet::default(), BitSet::default()), + |(mut deep_safety, mut shallow_safety), branch_occurrences| { + deep_safety.union_with(&branch_occurrences.deep_safety); + shallow_safety.union_with(&branch_occurrences.shallow_safety); + + (deep_safety, shallow_safety) + }); + + let branch_designator = self.current_branch_designator(); + + let (deep_safety, shallow_safety) = match self.branch_stack.last_mut() { + Some(latest_branch) => { + latest_branch.deep_safety.union_with(&deep_safety); + latest_branch.shallow_safety.union_with(&shallow_safety); + + (&latest_branch.deep_safety, &latest_branch.shallow_safety) + } + None => (&deep_safety, &shallow_safety) + }; + + for var_num in subsumed_hits.iter().cloned() { + let running_count = self.var_data.records[var_num].running_count; + let num_occurrences = self.var_data.records[var_num].num_occurrences; + + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, allocation) => { + let shallow_safety = VarSafetyStatus::needed_if( + shallow_safety.contains(var_num), + branch_designator, + ); + + let deep_safety = VarSafetyStatus::needed_if( + deep_safety.contains(var_num), + branch_designator, + ); + + if running_count < num_occurrences { + *allocation = PermVarAllocation::Done { shallow_safety, deep_safety }; + } + } + _ => unreachable!() + } + } + + if self.branch_stack.len() > 0 { + for var_num in subsumed_hits { + self.add_branch_occurrence(var_num); + } + } + } + + fn is_curr_arg_distinct_from(&self, var_num: usize) -> bool { + match self.shallow_temp_mappings.get(&self.arg_c).cloned() { + Some(t_var) => t_var != var_num, _ => false, } } - fn occurs_shallowly_in_head(&self, var: &String, r: usize) -> bool { - match self.bindings.get(var).unwrap() { - &VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)), + fn occurs_shallowly_in_head(&self, var_num: usize, r: usize) -> bool { + match &self.var_data.records[var_num].allocation { + VarAlloc::Temp { temp_var_data, term_loc: GenContext::Head, .. } => { + temp_var_data.use_set.contains(&(GenContext::Head, r)) + } _ => false, } } @@ -45,13 +200,13 @@ impl DebrayAllocator { #[inline] fn is_in_use(&self, r: usize) -> bool { let in_use_range = r <= self.arity && r >= self.arg_c; - in_use_range || self.in_use.contains(&r) + in_use_range || self.in_use.contains(r) } - fn alloc_with_cr(&self, var: &String) -> usize { - match self.bindings.get(var) { - Some(&VarData::Temp(_, _, ref tvd)) => { - for &(_, reg) in tvd.use_set.iter() { + fn alloc_with_cr(&self, var_num: usize) -> usize { + match &self.var_data.records[var_num].allocation { + VarAlloc::Temp { temp_var_data, .. } => { + for &(_, reg) in temp_var_data.use_set.iter() { if !self.is_in_use(reg) { return reg; } @@ -61,7 +216,7 @@ impl DebrayAllocator { for reg in self.temp_lb.. { if !self.is_in_use(reg) { - if !tvd.no_use_set.contains(®) { + if !temp_var_data.no_use_set.contains(reg) { result = reg; break; } @@ -74,10 +229,10 @@ impl DebrayAllocator { } } - fn alloc_with_ca(&self, var: &String) -> usize { - match self.bindings.get(var) { - Some(&VarData::Temp(_, _, ref tvd)) => { - for &(_, reg) in tvd.use_set.iter() { + fn alloc_with_ca(&self, var_num: usize) -> usize { + match &self.var_data.records[var_num].allocation { + VarAlloc::Temp { temp_var_data, .. } => { + for &(_, reg) in temp_var_data.use_set.iter() { if !self.is_in_use(reg) { return reg; } @@ -87,8 +242,8 @@ impl DebrayAllocator { for reg in self.temp_lb.. { if !self.is_in_use(reg) { - if !tvd.no_use_set.contains(®) { - if !tvd.conflict_set.contains(®) { + if !temp_var_data.no_use_set.contains(reg) { + if !temp_var_data.conflict_set.contains(reg) { result = reg; break; } @@ -102,22 +257,25 @@ impl DebrayAllocator { } } - fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc, usize)> { + fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(usize, usize)> { // we want to allocate a register to the k^{th} parameter, par_k. // par_k may not be a temporary variable. let k = self.arg_c; - match self.contents.get(&k) { + match self.shallow_temp_mappings.get(&k).cloned() { Some(t_var) => { // suppose this branch fires. then t_var is a // temp. var. belonging to the current chunk. // consider its use set. T == par_k iff // (GenContext::Last(_), k) is in t_var.use_set. - let tvd = self.bindings.get(t_var).unwrap(); - if let &VarData::Temp(_, _, ref tvd) = tvd { - if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) { - return Some((t_var.clone(), self.alloc_with_ca(t_var))); + match &self.var_data.records[t_var].allocation { + VarAlloc::Temp { temp_var_data, .. } => { + if !temp_var_data.use_set.contains(&(GenContext::Last(chunk_num), k)) { + return Some((t_var, self.alloc_with_ca(t_var))); + } + } + _ => { } } @@ -130,21 +288,21 @@ impl DebrayAllocator { fn evacuate_arg<'a, Target: CompilationTarget<'a>>( &mut self, chunk_num: usize, - code: &mut Code, + code: &mut CodeDeque, ) { match self.alloc_in_last_goal_hint(chunk_num) { - Some((var, r)) => { + Some((var_num, r)) => { let k = self.arg_c; if r != k { let r = RegType::Temp(r); - code.push(Target::move_to_register(r, k)); + code.push_back(Target::move_to_register(r, k)); - self.contents.swap_remove(&k); - self.contents.insert(r.reg_num(), var.clone()); + self.shallow_temp_mappings.swap_remove(&k); + self.shallow_temp_mappings.insert(r.reg_num(), var_num); - self.record_register(var, r); + self.var_data.records[var_num].allocation.set_register(r.reg_num()); self.in_use.insert(r.reg_num()); } } @@ -154,27 +312,27 @@ impl DebrayAllocator { fn alloc_reg_to_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: &String, + var_num: usize, lvl: Level, term_loc: GenContext, - target: &mut Vec, + target: &mut CodeDeque, ) -> usize { match term_loc { GenContext::Head => { if let Level::Shallow = lvl { self.evacuate_arg::(0, target); - self.alloc_with_cr(var) + self.alloc_with_cr(var_num) } else { - self.alloc_with_ca(var) + self.alloc_with_ca(var_num) } } - GenContext::Mid(_) => self.alloc_with_ca(var), + GenContext::Mid(_) => self.alloc_with_ca(var_num), GenContext::Last(chunk_num) => { if let Level::Shallow = lvl { self.evacuate_arg::(chunk_num, target); - self.alloc_with_cr(var) + self.alloc_with_cr(var_num) } else { - self.alloc_with_ca(var) + self.alloc_with_ca(var_num) } } } @@ -183,15 +341,15 @@ impl DebrayAllocator { fn alloc_reg_to_non_var(&mut self) -> usize { let mut final_index = 0; - while let Some(r) = self.free_list.pop() { - if !self.in_use.contains(&r) { + while let Some(r) = self.temp_free_list.pop() { + if !self.is_in_use(r) { self.in_use.insert(r); return r; } } for index in self.temp_lb.. { - if !self.in_use.contains(&index) { + if !self.in_use.contains(index) { final_index = index; self.in_use.insert(final_index); break; @@ -202,38 +360,219 @@ impl DebrayAllocator { final_index } - fn in_place(&self, var: &String, term_loc: GenContext, r: RegType, k: usize) -> bool { + fn in_place(&self, var_num: usize, term_loc: GenContext, r: RegType, k: usize) -> bool { match term_loc { GenContext::Head if !r.is_perm() => r.reg_num() == k, - _ => match self.bindings().get(var).unwrap() { - &VarData::Temp(_, o, _) if r.reg_num() == k => o == k, - _ => false, + _ => { + match &self.var_data.records[var_num].allocation { + &VarAlloc::Temp { temp_reg, .. } if r.reg_num() == k => + temp_reg == k, + _ => false, + } }, } } - pub fn add_to_free_list(&mut self, r: RegType) { + fn alloc_perm_var(&mut self, var_num: usize, chunk_num: usize) -> usize { + let p = if let Some(p) = self.pop_free_perm(chunk_num) { + p + } else { + let p = self.perm_lb; + self.perm_lb += 1; + + p + }; + + self.var_data.records[var_num].allocation = VarAlloc::Perm(p, PermVarAllocation::done()); + p + } + + pub(crate) fn add_reg_to_free_list(&mut self, r: RegType) { if let RegType::Temp(r) = r { - self.in_use.remove(&r); - self.free_list.push(r); + self.in_use.remove(r); + self.temp_free_list.push(r); } } pub fn reset_free_list(&mut self) { - self.free_list.clear(); + self.temp_free_list.clear(); + } + + #[inline(always)] + pub fn get_binding(&self, var_num: usize) -> RegType { + self.var_data.records[var_num].allocation.as_reg_type() + } + + pub fn num_perm_vars(&self) -> usize { + self.perm_lb - 1 + } + + pub fn increment_running_count(&mut self, var_num: usize) { + self.var_data.records[var_num].running_count += 1; + } + + fn add_perm_to_free_list(&mut self, chunk_num: usize, var_num: usize) { + match &self.var_data.records[var_num].allocation { + VarAlloc::Perm(..) => { + self.perm_free_list.push_back((chunk_num, var_num)); + } + _ => {} + } + } + + fn pop_free_perm(&mut self, chunk_num: usize) -> Option { + while let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() { + if chunk_num > perm_chunk_num { + self.perm_free_list.pop_front(); + + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(p, PermVarAllocation::Pending) if *p > 0 => { + return Some(std::mem::replace(p, 0)); + } + _ => { + } + } + } else { + return None; + } + } + + None + } + + pub(crate) fn free_var(&mut self, chunk_num: usize, var_num: usize) { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, allocation) => { + *allocation = PermVarAllocation::Pending; + self.add_perm_to_free_list(chunk_num, var_num); + } + _ => { + } + } + } + + pub(crate) fn mark_safe_var_unconditionally(&mut self, var_num: usize) { + let branch_designator = self.current_branch_designator(); + + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => { + *deep_safety = VarSafetyStatus::unneeded(branch_designator); + *shallow_safety = VarSafetyStatus::unneeded(branch_designator); + } + VarAlloc::Temp { safety, .. } => { + *safety = VarSafetyStatus::unneeded(branch_designator); + } + _ => unreachable!(), + } + } + + fn mark_safe_var(&mut self, var_num: usize, lvl: Level, term_loc: GenContext) { + let branch_designator = self.current_branch_designator(); + + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { deep_safety, shallow_safety, .. }) => { + // GetVariable in head chunk is considered safe. + if lvl == Level::Deep { + *deep_safety = VarSafetyStatus::unneeded(branch_designator); + *shallow_safety = VarSafetyStatus::unneeded(branch_designator); + } else if term_loc == GenContext::Head { + *shallow_safety = VarSafetyStatus::GloballyUnneeded; + } else { + 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 { ref mut to_perm_var_num, .. } => { + *to_perm_var_num = Some(var_num); + } + _ => unreachable!() + } + } + } + } + VarAlloc::Temp { ref mut safety, .. } => { + *safety = VarSafetyStatus::GloballyUnneeded; + } + _ => { + unreachable!() + } + } + } + + fn argument_to_value<'a, Target: CompilationTarget<'a>>( + &mut self, + var_num: usize, + r: RegType, + arg_c: usize, + ) -> Instruction { + let branch_designator = self.current_branch_designator(); + + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { ref mut shallow_safety, .. }) => { + if !self.in_tail_position || shallow_safety.is_unneeded(branch_designator) { + Target::argument_to_value(r, arg_c) + } else { + *shallow_safety = VarSafetyStatus::unneeded(branch_designator); + Target::unsafe_argument_to_value(r, arg_c) + } + } + VarAlloc::Temp { ref mut safety, .. } => { + if safety.is_unneeded(branch_designator) { + Target::argument_to_value(r, arg_c) + } else { + *safety = VarSafetyStatus::GloballyUnneeded; + Target::unsafe_argument_to_value(r, arg_c) + } + } + _ => { + unreachable!() + } + } + } + + fn subterm_to_value<'a, Target: CompilationTarget<'a>>( + &mut self, + var_num: usize, + r: RegType, + ) -> Instruction { + let branch_designator = self.current_branch_designator(); + + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, PermVarAllocation::Done { ref mut deep_safety, .. }) => { + if deep_safety.is_unneeded(branch_designator) { + Target::subterm_to_value(r) + } else { + *deep_safety = VarSafetyStatus::unneeded(branch_designator); + Target::unsafe_subterm_to_value(r) + } + } + VarAlloc::Temp { ref mut safety, .. } => { + if safety.is_unneeded(branch_designator) { + Target::subterm_to_value(r) + } else { + *safety = VarSafetyStatus::unneeded(branch_designator); + Target::unsafe_subterm_to_value(r) + } + } + _ => { + unreachable!() + } + } } } impl Allocator for DebrayAllocator { fn new() -> DebrayAllocator { - DebrayAllocator { + Self { + var_data: VarData::default(), + in_tail_position: false, arity: 0, arg_c: 1, temp_lb: 1, - bindings: IndexMap::with_hasher(FxBuildHasher::default()), - contents: IndexMap::with_hasher(FxBuildHasher::default()), - in_use: BTreeSet::new(), - free_list: vec![], + perm_lb: 1, + shallow_temp_mappings: IndexMap::with_hasher(FxBuildHasher::default()), + in_use: BitSet::default(), + temp_free_list: vec![], + perm_free_list: VecDeque::new(), + branch_stack: vec![], } } @@ -241,12 +580,12 @@ impl Allocator for DebrayAllocator { &mut self, lvl: Level, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, ) { let r = RegType::Temp(self.alloc_reg_to_non_var()); match lvl { - Level::Deep => code.push(Target::subterm_to_variable(r)), + Level::Deep => code.push_back(Target::subterm_to_variable(r)), Level::Root | Level::Shallow => { let k = self.arg_c; @@ -256,7 +595,7 @@ impl Allocator for DebrayAllocator { self.arg_c += 1; - code.push(Target::argument_to_variable(r, k)); + code.push_back(Target::argument_to_variable(r, k)); } }; } @@ -266,7 +605,7 @@ impl Allocator for DebrayAllocator { lvl: Level, term_loc: GenContext, cell: &'a Cell, - code: &mut Code, + code: &mut CodeDeque, ) { let r = cell.get(); @@ -293,39 +632,49 @@ impl Allocator for DebrayAllocator { fn mark_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: Rc, + var_num: usize, lvl: Level, cell: &'a Cell, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, ) { - let (r, is_new_var) = match self.get(var.clone()) { + let (r, is_new_var) = match self.get_binding(var_num) { RegType::Temp(0) => { - // here, r is temporary *and* unassigned. - let o = self.alloc_reg_to_var::(&var, lvl, term_loc, code); + let o = self.alloc_reg_to_var::(var_num, lvl, term_loc, code); cell.set(VarReg::Norm(RegType::Temp(o))); (RegType::Temp(o), true) } RegType::Perm(0) => { - let pr = cell.get().norm(); - self.record_register(var.clone(), pr); + let p = self.alloc_perm_var(var_num, term_loc.chunk_num()); + (RegType::Perm(p), true) + } + r @ RegType::Perm(_) => { + let is_new_var = match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, allocation) => if allocation.pending() { + *allocation = PermVarAllocation::done(); + true + } else { + false + }, + _ => unreachable!(), + }; - (pr, true) + (r, is_new_var) } r => (r, false), }; - self.mark_reserved_var::(var, lvl, cell, term_loc, code, r, is_new_var); + self.mark_reserved_var::(var_num, lvl, cell, term_loc, code, r, is_new_var); } fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( &mut self, - var: Rc, + var_num: usize, lvl: Level, cell: &'a Cell, term_loc: GenContext, - code: &mut Code, + code: &mut CodeDeque, r: RegType, is_new_var: bool, ) { @@ -333,86 +682,99 @@ impl Allocator for DebrayAllocator { Level::Root | Level::Shallow => { let k = self.arg_c; - if self.is_curr_arg_distinct_from(&var) { + if self.is_curr_arg_distinct_from(var_num) { self.evacuate_arg::(term_loc.chunk_num(), code); } - self.arg_c += 1; - cell.set(VarReg::ArgAndNorm(r, k)); - if !self.in_place(&var, term_loc, r, k) { + if !self.in_place(var_num, term_loc, r, k) { if is_new_var { - code.push(Target::argument_to_variable(r, k)); + self.mark_safe_var(var_num, lvl, term_loc); + code.push_back(Target::argument_to_variable(r, k)); } else { - code.push(Target::argument_to_value(r, k)); + code.push_back(self.argument_to_value::(var_num, r, k)); } } + + self.arg_c += 1; } Level::Deep if is_new_var => { if let GenContext::Head = term_loc { - if self.occurs_shallowly_in_head(&var, r.reg_num()) { - code.push(Target::subterm_to_value(r)); + if self.occurs_shallowly_in_head(var_num, r.reg_num()) { + code.push_back(self.subterm_to_value::(var_num, r)); } else { - code.push(Target::subterm_to_variable(r)); + self.mark_safe_var(var_num, lvl, term_loc); + code.push_back(Target::subterm_to_variable(r)); } } else { - code.push(Target::subterm_to_variable(r)); + self.mark_safe_var(var_num, lvl, term_loc); + code.push_back(Target::subterm_to_variable(r)); } } - Level::Deep => code.push(Target::subterm_to_value(r)), - }; + Level::Deep => code.push_back(self.subterm_to_value::(var_num, r)), + } + + let o = r.reg_num(); if !r.is_perm() { - let o = r.reg_num(); + self.shallow_temp_mappings.insert(o, var_num); + } else if r.is_perm() && is_new_var { + self.add_branch_occurrence(var_num); + } - self.contents.insert(o, var.clone()); - self.record_register(var.clone(), r); - self.in_use.insert(o); + let record = &mut self.var_data.records[var_num]; + + record.allocation.set_register(o); + + if record.running_count < record.num_occurrences { + record.running_count += 1; + } else { + self.free_var(term_loc.chunk_num(), var_num); + } + + self.in_use.insert(o); + } + + fn mark_cut_var(&mut self, var_num: usize, chunk_num: usize) -> RegType { + match self.get_binding(var_num) { + RegType::Perm(0) | RegType::Temp(0) => { + RegType::Perm(self.alloc_perm_var(var_num, chunk_num)) + } + r => r, } } fn reset(&mut self) { - self.bindings.clear(); - self.contents.clear(); + self.perm_lb = 1; + self.shallow_temp_mappings.clear(); self.in_use.clear(); - self.free_list.clear(); + self.temp_free_list.clear(); } fn reset_contents(&mut self) { - self.contents.clear(); self.in_use.clear(); - self.free_list.clear(); + self.shallow_temp_mappings.clear(); + self.temp_free_list.clear(); } fn advance_arg(&mut self) { self.arg_c += 1; } - fn bindings(&self) -> &AllocVarDict { - &self.bindings - } - - fn bindings_mut(&mut self) -> &mut AllocVarDict { - &mut self.bindings - } - - fn take_bindings(self) -> AllocVarDict { - self.bindings - } - fn reset_at_head(&mut self, args: &Vec) { self.reset_arg(args.len()); self.arity = args.len(); for (idx, arg) in args.iter().enumerate() { if let &Term::Var(_, ref var) = arg { - let r = self.get(var.clone()); + let var_num = var.to_var_num().unwrap(); + let r = self.get_binding(var_num); if !r.is_perm() && r.reg_num() == 0 { self.in_use.insert(idx + 1); - self.contents.insert(idx + 1, var.clone()); - self.record_register(var.clone(), temp_v!(idx + 1)); + self.shallow_temp_mappings.insert(idx + 1, var_num); + self.var_data.records[var_num].allocation.set_register(idx + 1); } } } diff --git a/src/fixtures.rs b/src/fixtures.rs deleted file mode 100644 index 1f812e2c..00000000 --- a/src/fixtures.rs +++ /dev/null @@ -1,436 +0,0 @@ -use crate::parser::ast::*; - -use crate::forms::*; -use crate::instructions::*; -use crate::iterators::*; - -use indexmap::{IndexMap, IndexSet}; - -use std::cell::Cell; -use std::collections::BTreeSet; -use std::mem::swap; -use std::rc::Rc; -use std::vec::Vec; - -// labeled with chunk numbers. -#[derive(Debug)] -pub(crate) enum VarStatus { - Perm(usize), - Temp(usize, TempVarData), // Perm(chunk_num) | Temp(chunk_num, _) -} - -pub(crate) type OccurrenceSet = BTreeSet<(GenContext, usize)>; - -// Perm: 0 initially, a stack register once processed. -// Temp: labeled with chunk_num and temp offset (unassigned if 0). -#[derive(Debug)] -pub(crate) enum VarData { - Perm(usize), - Temp(usize, usize, TempVarData), -} - -impl VarData { - pub(crate) fn as_reg_type(&self) -> RegType { - match self { - &VarData::Temp(_, r, _) => RegType::Temp(r), - &VarData::Perm(r) => RegType::Perm(r), - } - } -} - -#[derive(Debug)] -pub(crate) struct TempVarData { - pub(crate) last_term_arity: usize, - pub(crate) use_set: OccurrenceSet, - pub(crate) no_use_set: BTreeSet, - pub(crate) conflict_set: BTreeSet, -} - -impl TempVarData { - pub(crate) fn new(last_term_arity: usize) -> Self { - TempVarData { - last_term_arity: last_term_arity, - use_set: BTreeSet::new(), - no_use_set: BTreeSet::new(), - conflict_set: BTreeSet::new(), - } - } - - pub(crate) fn uses_reg(&self, reg: usize) -> bool { - for &(_, nreg) in self.use_set.iter() { - if reg == nreg { - return true; - } - } - - return false; - } - - pub(crate) fn populate_conflict_set(&mut self) { - if self.last_term_arity > 0 { - let arity = self.last_term_arity; - let mut conflict_set: BTreeSet = (1..arity).collect(); - - for &(_, reg) in self.use_set.iter() { - conflict_set.remove(®); - } - - self.conflict_set = conflict_set; - } - } -} - -type VariableFixture<'a> = (VarStatus, Vec<&'a Cell>); - -#[derive(Debug)] -pub(crate) struct VariableFixtures<'a> { - perm_vars: IndexMap, VariableFixture<'a>>, - last_chunk_temp_vars: IndexSet>, -} - -impl<'a> VariableFixtures<'a> { - pub(crate) fn new() -> Self { - VariableFixtures { - perm_vars: IndexMap::new(), - last_chunk_temp_vars: IndexSet::new(), - } - } - - pub(crate) fn insert(&mut self, var: Rc, vs: VariableFixture<'a>) { - self.perm_vars.insert(var, vs); - } - - pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Rc) { - self.last_chunk_temp_vars.insert(var); - } - - // computes no_use and conflict sets for all temp vars. - pub(crate) fn populate_restricting_sets(&mut self) { - // three stages: - // 1. move the use sets of each variable to a local IndexMap, use_set - // (iterate mutably, swap mutable refs). - // 2. drain use_set. For each use set of U, add into the - // no-use sets of appropriate variables T =/= U. - // 3. Move the use sets back to their original locations in the fixture. - // Compute the conflict set of u. - - // 1. - let mut use_sets: IndexMap, OccurrenceSet> = IndexMap::new(); - - for (var, &mut (ref mut var_status, _)) in self.iter_mut() { - if let &mut VarStatus::Temp(_, ref mut var_data) = var_status { - let mut use_set = OccurrenceSet::new(); - - swap(&mut var_data.use_set, &mut use_set); - use_sets.insert((*var).clone(), use_set); - } - } - - for (u, use_set) in use_sets.drain(..) { - // 2. - for &(term_loc, reg) in use_set.iter() { - if let GenContext::Last(cn_u) = term_loc { - for (ref t, &mut (ref mut var_status, _)) in self.iter_mut() { - if let &mut VarStatus::Temp(cn_t, ref mut t_data) = var_status { - if cn_u == cn_t && *u != ***t { - if !t_data.uses_reg(reg) { - t_data.no_use_set.insert(reg); - } - } - } - } - } - } - - // 3. - match self.get_mut(u).unwrap() { - &mut (VarStatus::Temp(_, ref mut u_data), _) => { - u_data.use_set = use_set; - u_data.populate_conflict_set(); - } - _ => {} - }; - } - } - - fn get_mut(&mut self, u: Rc) -> Option<&mut VariableFixture<'a>> { - self.perm_vars.get_mut(&u) - } - - fn iter_mut(&mut self) -> indexmap::map::IterMut, VariableFixture<'a>> { - self.perm_vars.iter_mut() - } - - fn record_temp_info(&mut self, tvd: &mut TempVarData, arg_c: usize, term_loc: GenContext) { - match term_loc { - GenContext::Head | GenContext::Last(_) => { - tvd.use_set.insert((term_loc, arg_c)); - } - _ => {} - }; - } - - pub(crate) fn vars_above_threshold(&self, index: usize) -> usize { - let mut var_count = 0; - - for &(ref var_status, _) in self.values() { - if let &VarStatus::Perm(i) = var_status { - if i > index { - var_count += 1; - } - } - } - - var_count - } - - pub(crate) fn mark_vars_in_chunk(&mut self, iter: I, lt_arity: usize, term_loc: GenContext) - where - I: Iterator>, - { - let chunk_num = term_loc.chunk_num(); - let mut arg_c = 1; - - for term_ref in iter { - if let &TermRef::Var(lvl, cell, ref var) = &term_ref { - let mut status = self.perm_vars.swap_remove(var).unwrap_or(( - VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)), - Vec::new(), - )); - - status.1.push(cell); - - match status.0 { - VarStatus::Temp(cn, ref mut tvd) if cn == chunk_num => { - if let Level::Shallow = lvl { - self.record_temp_info(tvd, arg_c, term_loc); - } - } - _ => status.0 = VarStatus::Perm(chunk_num), - }; - - self.perm_vars.insert(var.clone(), status); - } - - if let Level::Shallow = term_ref.level() { - arg_c += 1; - } - } - } - - pub(crate) fn into_iter(self) -> indexmap::map::IntoIter, VariableFixture<'a>> { - self.perm_vars.into_iter() - } - - fn values(&self) -> indexmap::map::Values, VariableFixture<'a>> { - self.perm_vars.values() - } - - pub(crate) fn size(&self) -> usize { - self.perm_vars.len() - } - - pub(crate) fn set_perm_vals(&self, has_deep_cuts: bool) { - let mut values_vec: Vec<_> = self - .values() - .filter_map(|ref v| match &v.0 { - &VarStatus::Perm(i) => Some((i, &v.1)), - _ => None, - }) - .collect(); - - values_vec.sort_by_key(|ref v| v.0); - - let offset = has_deep_cuts as usize; - - for (i, (_, cells)) in values_vec.into_iter().rev().enumerate() { - for cell in cells { - cell.set(VarReg::Norm(RegType::Perm(i + 1 + offset))); - } - } - } -} - -#[derive(Debug)] -pub(crate) struct UnsafeVarMarker { - pub(crate) unsafe_perm_vars: IndexMap, - pub(crate) unsafe_temp_vars: IndexSet, - pub(crate) safe_perm_vars: IndexSet, - pub(crate) safe_temp_vars: IndexSet, - pub(crate) temp_vars_to_perm_vars: IndexMap, - pub(crate) perm_vars_to_temp_vars: IndexMap, -} - -impl UnsafeVarMarker { - pub(crate) fn new() -> Self { - UnsafeVarMarker { - unsafe_perm_vars: IndexMap::new(), - unsafe_temp_vars: IndexSet::new(), - safe_perm_vars: IndexSet::new(), - safe_temp_vars: IndexSet::new(), - temp_vars_to_perm_vars: IndexMap::new(), - perm_vars_to_temp_vars: IndexMap::new(), - } - } - - pub(crate) fn from_fact_vars(safe_vars: IndexSet) -> Self { - let mut unsafe_var_marker = Self::new(); - - for r in safe_vars { - unsafe_var_marker.mark_var_as_safe(r); - } - - unsafe_var_marker - } - - fn mark_var_as_safe(&mut self, r: RegType) { - match r { - RegType::Temp(t) => { - self.safe_temp_vars.insert(t); - } - RegType::Perm(p) => { - self.safe_perm_vars.insert(p); - } - }; - } - - fn mark_var_as_unsafe(&mut self, r: RegType, phase: usize) { - match r { - RegType::Temp(t) => { - self.unsafe_temp_vars.insert(t); - } - RegType::Perm(p) => { - self.unsafe_perm_vars.insert(p, phase); - } - } - } - - // returns true if the instruction at *query_instr cannot be - // changed by mark_unsafe_vars. - fn mark_safe_vars(&mut self, query_instr: &Instruction) -> bool { - match query_instr { - &Instruction::PutVariable(r @ RegType::Temp(_), _) | - &Instruction::SetVariable(r) => { - self.mark_var_as_safe(r); - true - } - &Instruction::PutVariable(RegType::Perm(p), t) => { - self.temp_vars_to_perm_vars.insert(t, p); - true - } - &Instruction::CallIs(RegType::Temp(t), ..) => { - if let Some(p) = self.temp_vars_to_perm_vars.get(&t) { - self.mark_var_as_safe(RegType::Perm(*p)); - } - - true - } - _ => false, - } - } - - fn mark_phase(&mut self, query_instr: &Instruction, phase: usize) { - match query_instr { - &Instruction::PutValue(r @ RegType::Perm(_), _) | - &Instruction::SetValue(r) => { - self.mark_var_as_unsafe(r, phase); - } - _ => {} - } - } - - fn mark_unsafe_perm_vars(&mut self, query_instr: &mut Instruction, phase: usize) { - match query_instr { - &mut Instruction::PutValue(RegType::Perm(p), arg) - if !self.safe_perm_vars.contains(&p) => { - if let Some(ph) = self.unsafe_perm_vars.swap_remove(&p) { - if ph == phase { - *query_instr = Instruction::PutUnsafeValue(p, arg); - self.perm_vars_to_temp_vars.insert(p, arg); - } else { - self.unsafe_perm_vars.insert(p, ph); - } - } - } - &mut Instruction::SetValue(r @ RegType::Perm(p)) => - if let Some(t) = self.perm_vars_to_temp_vars.get(&p) { - *query_instr = Instruction::SetValue(RegType::Temp(*t)); - } else { - *query_instr = Instruction::SetLocalValue(r); - } - _ => {} - } - } - - fn mark_unsafe_temp_vars(&mut self, query_instr: &mut Instruction) { - match query_instr { - &mut Instruction::SetValue(r @ RegType::Temp(t)) - if !self.safe_temp_vars.contains(&t) => { - *query_instr = Instruction::SetLocalValue(r); - - self.safe_temp_vars.insert(t); - self.unsafe_temp_vars.remove(&t); - } - _ => { - } - } - } - - fn clear_temp_vars(&mut self) { - self.safe_temp_vars.clear(); - self.unsafe_temp_vars.clear(); - self.temp_vars_to_perm_vars.clear(); - } - - pub(crate) fn mark_unsafe_instrs(&mut self, code: &mut Code) { - if code.is_empty() { - return; - } - - let mut code_index = 0; - - for phase in 0.. { - while code[code_index].is_query_instr() { - let query_instr = &mut code[code_index]; - - if !self.mark_safe_vars(query_instr) { - self.mark_phase(query_instr, phase); - self.mark_unsafe_temp_vars(query_instr); - } - - code_index += 1; - } - - while code_index < code.len() && !code[code_index].is_query_instr() { - self.mark_safe_vars(&code[code_index]); - code_index += 1; - } - - self.clear_temp_vars(); - - if code_index >= code.len() { - break; - } - } - - code_index = 0; - - for phase in 0.. { - while code[code_index].is_query_instr() { - let query_instr = &mut code[code_index]; - self.mark_unsafe_perm_vars(query_instr, phase); - code_index += 1; - } - - // ensure phase->instruction assignments match those of - // the previous for loop. - while code_index < code.len() && !code[code_index].is_query_instr() { - code_index += 1; - } - - if code_index >= code.len() { - break; - } - } - } -} diff --git a/src/forms.rs b/src/forms.rs index 1c014587..627fb4b2 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -1,6 +1,7 @@ use crate::arena::*; use crate::atom_table::*; use crate::instructions::*; +use crate::machine::disjuncts::VarData; use crate::machine::heap::*; use crate::machine::loader::PredicateQueue; use crate::machine::machine_errors::*; @@ -19,26 +20,23 @@ use std::cell::Cell; use std::collections::VecDeque; use std::convert::TryFrom; use std::fmt; -use std::ops::AddAssign; +use std::ops::{AddAssign, Deref, DerefMut}; use std::path::PathBuf; -use std::rc::Rc; use crate::{is_infix, is_postfix}; pub type PredicateKey = (Atom, usize); // name, arity. -pub type Predicate = Vec; - +/* // vars of predicate, toplevel offset. Vec is always a vector // of vars (we get their adjoining cells this way). pub type JumpStub = Vec; +*/ -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum TopLevel { - Fact(Term), // Term, line_num, col_num - Predicate(Predicate), - Query(Vec), - Rule(Rule), // Rule, line_num, col_num + Fact(Fact, VarData), // Term, line_num, col_num + Rule(Rule, VarData), // Rule, line_num, col_num } #[derive(Debug, Clone, Copy)] @@ -57,7 +55,7 @@ impl AppendOrPrepend { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Level { Deep, Root, @@ -79,38 +77,144 @@ pub enum CallPolicy { Counted, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ChunkType { + Head, + Mid, + Last, +} + +#[derive(Debug)] +pub enum RootIterationPolicy { + Iterated, + NotIterated, +} + +impl RootIterationPolicy { + #[inline(always)] + pub fn iterable(&self) -> bool { + if let RootIterationPolicy::Iterated = self { + true + } else { + false + } + } +} + +impl ChunkType { + #[inline(always)] + pub fn to_gen_context(self, chunk_num: usize) -> GenContext { + match self { + ChunkType::Head => GenContext::Head, + ChunkType::Mid => GenContext::Mid(chunk_num), + ChunkType::Last => GenContext::Last(chunk_num), + } + } + + #[inline(always)] + pub fn is_last(self) -> bool { + self == ChunkType::Last + } +} + +#[derive(Debug)] +pub enum ChunkedTerms { + Branch(Vec>), + Chunk(VecDeque), +} + +#[derive(Debug)] +pub struct ChunkedTermVec { + pub chunk_vec: VecDeque, +} + +impl Deref for ChunkedTermVec { + type Target = VecDeque; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.chunk_vec + } +} + +impl DerefMut for ChunkedTermVec { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.chunk_vec + } +} + +impl ChunkedTermVec { + #[inline] + pub fn new() -> Self { + Self { chunk_vec: VecDeque::new() } + } + + pub fn reserve_branch(&mut self, capacity: usize) { + self.chunk_vec.push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity))); + } + + pub fn push_branch_arm(&mut self, branch: VecDeque) { + match self.chunk_vec.back_mut().unwrap() { + ChunkedTerms::Branch(branches) => { + branches.push(branch); + } + ChunkedTerms::Chunk(_) => { + self.chunk_vec.push_back(ChunkedTerms::Branch(vec![branch])); + } + } + } + + #[inline] + pub fn add_chunk(&mut self) { + self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![]))); + } + + pub fn push_chunk_term(&mut self, term: QueryTerm) { + match self.chunk_vec.back_mut() { + Some(ChunkedTerms::Branch(_)) => { + self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term]))); + } + Some(ChunkedTerms::Chunk(chunk)) => { + chunk.push_back(term); + } + None => { + self.chunk_vec.push_back(ChunkedTerms::Chunk(VecDeque::from(vec![term]))); + } + } + } +} + +#[derive(Debug)] pub enum QueryTerm { // register, clause type, subterms, clause call policy. Clause(Cell, ClauseType, Vec, CallPolicy), - BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q. - UnblockedCut(Cell), - GetLevelAndUnify(Cell, Rc), - Jump(JumpStub), + Fail, + LocalCut(usize), // var_num + GlobalCut(usize), // var_num + GetCutPoint { var_num: usize, prev_b: bool }, + GetLevel(usize), // var_num } impl QueryTerm { - pub(crate) fn set_call_policy(&mut self, cp: CallPolicy) { - match self { - &mut QueryTerm::Clause(_, _, _, ref mut clause_cp) => *clause_cp = cp, - _ => {} - } - } - pub(crate) fn arity(&self) -> usize { match self { &QueryTerm::Clause(_, _, ref subterms, ..) => subterms.len(), - &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => 0, - &QueryTerm::Jump(ref vars) => vars.len(), - &QueryTerm::GetLevelAndUnify(..) => 1, + &QueryTerm::GetLevel(_) | &QueryTerm::GetCutPoint { .. } => 1, + _ => 0, } } } -#[derive(Debug, Clone)] +#[derive(Debug)] +pub struct Fact { + pub(crate) head: Term, +} + +#[derive(Debug)] pub struct Rule { - pub(crate) head: (Atom, Vec, QueryTerm), - pub(crate) clauses: Vec, + pub(crate) head: (Atom, Vec), + pub(crate) clauses: ChunkedTermVec, } #[derive(Clone, Debug, Hash)] @@ -201,29 +305,29 @@ impl ClauseInfo for Rule { impl ClauseInfo for PredicateClause { fn name(&self) -> Option { match self { - &PredicateClause::Fact(ref term, ..) => term.name(), + &PredicateClause::Fact(ref term, ..) => term.head.name(), &PredicateClause::Rule(ref rule, ..) => rule.name(), } } fn arity(&self) -> usize { match self { - &PredicateClause::Fact(ref term, ..) => term.arity(), + &PredicateClause::Fact(ref term, ..) => term.head.arity(), &PredicateClause::Rule(ref rule, ..) => rule.arity(), } } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum PredicateClause { - Fact(Term), - Rule(Rule), + Fact(Fact, VarData), + Rule(Rule, VarData), } impl PredicateClause { pub(crate) fn args(&self) -> Option<&[Term]> { match self { - PredicateClause::Fact(term, ..) => match term { + PredicateClause::Fact(term, ..) => match &term.head { Term::Clause(_, _, args) => Some(&args), _ => None, }, diff --git a/src/heap_print.rs b/src/heap_print.rs index 21835d49..f846dea1 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -481,7 +481,7 @@ pub struct HCPrinter<'a, Outputter> { state_stack: Vec, toplevel_spec: Option, last_item_idx: usize, - pub var_names: IndexMap>, + pub var_names: IndexMap, pub numbervars_offset: Integer, pub numbervars: bool, pub quoted: bool, @@ -815,7 +815,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { if let Some(var) = self.var_names.get(&cell) { read_heap_cell!(cell, (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => { - return Some(format!("{}", var.as_str())); + return Some(var.borrow().to_string()); } _ => { self.iter.push_stack(h); @@ -858,10 +858,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { // short-circuits handle_heap_term. // self.iter.pop_stack(); - let var_str = var.as_str(); + let var_str = var.borrow().to_string(); - push_space_if_amb!(self, var_str, { - append_str!(self, var_str); + push_space_if_amb!(self, &var_str, { + append_str!(self, &var_str); }); None @@ -873,8 +873,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { Some(var) => { // If the term is bound to a named variable, // print the variable's name to output. - push_space_if_amb!(self, &var, { - append_str!(self, &var); + let var_str = var.borrow().to_string(); + + push_space_if_amb!(self, &var_str, { + append_str!(self, &var_str); }); } None => { @@ -1739,9 +1741,7 @@ mod tests { heap_loc_as_cell!(0) ); - printer - .var_names - .insert(list_loc_as_cell!(1), Rc::new("L".to_string())); + printer.var_names.insert(list_loc_as_cell!(1), VarPtr::from("L")); let output = printer.print(); @@ -1808,9 +1808,7 @@ mod tests { heap_loc_as_cell!(0) ); - printer - .var_names - .insert(list_loc_as_cell!(1), Rc::new("L".to_string())); + printer.var_names.insert(list_loc_as_cell!(1), VarPtr::from("L")); let output = printer.print(); diff --git a/src/iterators.rs b/src/iterators.rs index 62054b04..adec2e4c 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -5,9 +5,7 @@ use crate::parser::ast::*; use std::cell::Cell; use std::collections::VecDeque; -use std::fmt; use std::iter::*; -use std::rc::Rc; use std::vec::Vec; #[derive(Debug, Clone)] @@ -18,34 +16,36 @@ pub(crate) enum TermRef<'a> { Clause(Level, &'a Cell, Atom, &'a Vec), PartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), - Var(Level, &'a Cell, Rc), + Var(Level, &'a Cell, VarPtr), } +/* impl<'a> TermRef<'a> { - pub(crate) fn level(self) -> Level { + pub(crate) fn level(&self) -> Level { match self { - TermRef::AnonVar(lvl) - | TermRef::Cons(lvl, ..) - | TermRef::Literal(lvl, ..) - | TermRef::Var(lvl, ..) - | TermRef::Clause(lvl, ..) - | TermRef::CompleteString(lvl, ..) - | TermRef::PartialString(lvl, ..) => lvl, + TermRef::AnonVar(lvl) | + TermRef::Cons(lvl, ..) | + TermRef::Literal(lvl, ..) | + TermRef::Var(lvl, ..) | + TermRef::Clause(lvl, ..) | + TermRef::CompleteString(lvl, ..) | + TermRef::PartialString(lvl, ..) => *lvl, } } } +*/ #[derive(Debug)] pub(crate) enum TermIterState<'a> { AnonVar(Level), - Literal(Level, &'a Cell, &'a Literal), Clause(Level, usize, &'a Cell, Atom, &'a Vec), + Literal(Level, &'a Cell, &'a Literal), InitialCons(Level, &'a Cell, &'a Term, &'a Term), FinalCons(Level, &'a Cell, &'a Term, &'a Term), InitialPartialString(Level, &'a Cell, &'a String, &'a Box), FinalPartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), - Var(Level, &'a Cell, Rc), + Var(Level, &'a Cell, VarPtr), } impl<'a> TermIterState<'a> { @@ -65,7 +65,7 @@ impl<'a> TermIterState<'a> { Term::CompleteString(cell, atom) => { TermIterState::CompleteString(lvl, cell, *atom) } - Term::Var(cell, var) => TermIterState::Var(lvl, cell, var.clone()), + Term::Var(cell, var_ptr) => TermIterState::Var(lvl, cell, var_ptr.clone()), } } } @@ -77,10 +77,10 @@ pub(crate) struct QueryIterator<'a> { impl<'a> QueryIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { - self.state_stack - .push(TermIterState::subterm_to_state(lvl, term)); + self.state_stack.push(TermIterState::subterm_to_state(lvl, term)); } + /* fn from_rule_head_clause(terms: &'a Vec) -> Self { let state_stack = terms .iter() @@ -90,6 +90,7 @@ impl<'a> QueryIterator<'a> { QueryIterator { state_stack } } + */ fn from_term(term: &'a Term) -> Self { let state = match term { @@ -106,7 +107,7 @@ impl<'a> QueryIterator<'a> { *name, terms, ), - Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, var.clone()), + Term::Var(cell, var_ptr) => TermIterState::Var(Level::Root, cell, var_ptr.clone()), }; QueryIterator { @@ -114,46 +115,24 @@ impl<'a> QueryIterator<'a> { } } - fn new(term: &'a QueryTerm) -> Self { + fn extend_state(&mut self, lvl: Level, term: &'a QueryTerm) { match term { &QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => { - let state = TermIterState::Clause(Level::Root, 1, cell, atom!("$call"), terms); - QueryIterator { - state_stack: vec![state], - } + self.state_stack.push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms)); } &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => { - let state = TermIterState::Clause(Level::Root, 0, cell, ct.name(), terms); - QueryIterator { - state_stack: vec![state], - } + self.state_stack.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms)); } - &QueryTerm::UnblockedCut(ref cell) => { - let state = TermIterState::Var(Level::Root, cell, Rc::new("!".to_string())); - QueryIterator { - state_stack: vec![state], - } + _ => { } - &QueryTerm::GetLevelAndUnify(ref cell, ref var) => { - let state = TermIterState::Var(Level::Root, cell, var.clone()); - QueryIterator { - state_stack: vec![state], - } - } - &QueryTerm::Jump(ref vars) => { - let state_stack = vars - .iter() - .rev() - .map(|t| TermIterState::subterm_to_state(Level::Shallow, t)) - .collect(); - - QueryIterator { state_stack } - } - &QueryTerm::BlockedCut => QueryIterator { - state_stack: vec![], - }, } } + + pub fn new(term: &'a QueryTerm) -> Self { + let mut iter = QueryIterator { state_stack: vec![] }; + iter.extend_state(Level::Root, term); + iter + } } impl<'a> Iterator for QueryIterator<'a> { @@ -212,8 +191,8 @@ impl<'a> Iterator for QueryIterator<'a> { TermIterState::Literal(lvl, cell, constant) => { return Some(TermRef::Literal(lvl, cell, constant)); } - TermIterState::Var(lvl, cell, var) => { - return Some(TermRef::Var(lvl, cell, var)); + TermIterState::Var(lvl, cell, var_ptr) => { + return Some(TermRef::Var(lvl, cell, var_ptr)); } }; } @@ -225,7 +204,7 @@ impl<'a> Iterator for QueryIterator<'a> { #[derive(Debug)] pub(crate) struct FactIterator<'a> { state_queue: VecDeque>, - iterable_root: bool, + iterable_root: RootIterationPolicy, } impl<'a> FactIterator<'a> { @@ -242,11 +221,11 @@ impl<'a> FactIterator<'a> { FactIterator { state_queue, - iterable_root: false, + iterable_root: RootIterationPolicy::NotIterated, } } - fn new(term: &'a Term, iterable_root: bool) -> Self { + fn new(term: &'a Term, iterable_root: RootIterationPolicy) -> Self { let states = match term { Term::AnonVar => { vec![TermIterState::AnonVar(Level::Root)] @@ -278,8 +257,8 @@ impl<'a> FactIterator<'a> { Term::Literal(cell, constant) => { vec![TermIterState::Literal(Level::Root, cell, constant)] } - Term::Var(cell, var) => { - vec![TermIterState::Var(Level::Root, cell, var.clone())] + Term::Var(cell, var_ptr) => { + vec![TermIterState::Var(Level::Root, cell, var_ptr.clone())] } }; @@ -305,7 +284,7 @@ impl<'a> Iterator for FactIterator<'a> { } match lvl { - Level::Root if !self.iterable_root => continue, + Level::Root if !self.iterable_root.iterable() => continue, _ => return Some(TermRef::Clause(lvl, cell, name, child_terms)), }; } @@ -325,8 +304,8 @@ impl<'a> Iterator for FactIterator<'a> { TermIterState::Literal(lvl, cell, constant) => { return Some(TermRef::Literal(lvl, cell, constant)) } - TermIterState::Var(lvl, cell, var) => { - return Some(TermRef::Var(lvl, cell, var)); + TermIterState::Var(lvl, cell, var_ptr) => { + return Some(TermRef::Var(lvl, cell, var_ptr)); } _ => {} } @@ -340,193 +319,130 @@ pub(crate) fn post_order_iter<'a>(term: &'a Term) -> QueryIterator<'a> { QueryIterator::from_term(term) } -pub(crate) fn breadth_first_iter<'a>(term: &'a Term, iterable_root: bool) -> FactIterator<'a> { +pub(crate) fn breadth_first_iter<'a>(term: &'a Term, iterable_root: RootIterationPolicy) -> FactIterator<'a> { FactIterator::new(term, iterable_root) } +#[derive(Debug, Copy, Clone)] +enum ClauseIteratorState<'a> { + RemainingChunks(&'a VecDeque, usize), + RemainingBranches(&'a Vec>, usize), +} + +#[derive(Debug, Clone)] +pub(crate) enum ClauseItem<'a> { + FirstBranch(usize), + NextBranch, + BranchEnd(usize), + Chunk(&'a VecDeque), +} + #[derive(Debug)] -pub(crate) enum ChunkedTerm<'a> { - HeadClause(Atom, &'a Vec), - BodyTerm(&'a QueryTerm), +pub(crate) struct ClauseIterator<'a> { + state_stack: Vec>, + remaining_chunks_on_stack: usize, } -pub(crate) fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterator<'a> { - QueryIterator::new(query_term) -} - -impl<'a> ChunkedTerm<'a> { - pub(crate) fn post_order_iter(&self) -> QueryIterator<'a> { - match self { - &ChunkedTerm::BodyTerm(qt) => QueryIterator::new(qt), - &ChunkedTerm::HeadClause(_, terms) => QueryIterator::from_rule_head_clause(terms), +fn state_from_chunked_terms<'a>(chunk_vec: &'a VecDeque) -> ClauseIteratorState<'a> { + if chunk_vec.len() == 1 { + if let Some(ChunkedTerms::Branch(ref branches)) = chunk_vec.front() { + return ClauseIteratorState::RemainingBranches(branches, 0); } } + + ClauseIteratorState::RemainingChunks(chunk_vec, 0) } -fn contains_cut_var<'a, Iter: Iterator>(terms: Iter) -> bool { - for term in terms { - if let &Term::Var(_, ref var) = term { - if var.as_str() == "!" { - return true; +impl<'a> ClauseIterator<'a> { + pub fn new(clauses: &'a ChunkedTermVec) -> Self { + match state_from_chunked_terms(&clauses.chunk_vec) { + state @ ClauseIteratorState::RemainingBranches(..) => { + Self { + state_stack: vec![state], + remaining_chunks_on_stack: 0, + } + } + state @ ClauseIteratorState::RemainingChunks(..) => { + Self { + state_stack: vec![state], + remaining_chunks_on_stack: 1, + } } } } - false -} - -pub(crate) struct ChunkedIterator<'a> { - pub(crate) chunk_num: usize, - iter: Box> + 'a>, - deep_cut_encountered: bool, - cut_var_in_head: bool, -} - -impl<'a> fmt::Debug for ChunkedIterator<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("ChunkedIterator") - .field("chunk_num", &self.chunk_num) - // Hacky solution. - .field("iter", &"Box> + 'a>") - .field("deep_cut_encountered", &self.deep_cut_encountered) - .field("cut_var_in_head", &self.cut_var_in_head) - .finish() + #[inline(always)] + pub fn in_tail_position(&self) -> bool { + self.remaining_chunks_on_stack == 0 } -} -type ChunkedIteratorItem<'a> = (usize, usize, Vec>); -type RuleBodyIteratorItem<'a> = (usize, usize, Vec<&'a QueryTerm>); + fn branch_end_depth(&mut self) -> usize { + let mut depth = 1; -impl<'a> ChunkedIterator<'a> { - pub(crate) fn rule_body_iter(self) -> Box> + 'a> { - Box::new(self.filter_map(|(cn, lt_arity, terms)| { - let filtered_terms: Vec<_> = terms - .into_iter() - .filter_map(|ct| match ct { - ChunkedTerm::BodyTerm(qt) => Some(qt), - _ => None, - }) - .collect(); - - if filtered_terms.is_empty() { - None - } else { - Some((cn, lt_arity, filtered_terms)) + while let Some(state) = self.state_stack.pop() { + match state { + ClauseIteratorState::RemainingBranches(terms, focus) if terms.len() == focus => { + depth += 1; + } + _ => { + self.state_stack.push(state); + break; + } } - })) - } - - pub(crate) fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec) -> Self { - let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); - let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); - - ChunkedIterator { - chunk_num: 0, - iter: Box::new(iter), - deep_cut_encountered: false, - cut_var_in_head: false, - } - } - - pub(crate) fn from_rule(rule: &'a Rule) -> Self { - let &Rule { - head: (ref name, ref args, ref p1), - ref clauses, - } = rule; - - let iter = once(ChunkedTerm::HeadClause(name.clone(), args)); - let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); - let iter = iter.chain(inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)))); - - ChunkedIterator { - chunk_num: 0, - iter: Box::new(iter), - deep_cut_encountered: false, - cut_var_in_head: false, - } - } - - pub(crate) fn encountered_deep_cut(&self) -> bool { - self.deep_cut_encountered - } - - fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec>) { - let mut arity = 0; - let mut item = Some(term); - let mut result = Vec::new(); - - while let Some(term) = item { - match term { - ChunkedTerm::HeadClause(_, terms) => { - if contains_cut_var(terms.iter()) { - self.cut_var_in_head = true; - } - - result.push(term); - } - ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => { - result.push(term); - arity = vars.len(); - - if contains_cut_var(vars.iter()) && !self.cut_var_in_head { - self.deep_cut_encountered = true; - } - - break; - } - ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => { - result.push(term); - - if self.chunk_num > 0 { - self.deep_cut_encountered = true; - } - } - ChunkedTerm::BodyTerm(&QueryTerm::GetLevelAndUnify(..)) => { - self.deep_cut_encountered = true; - - result.push(term); - arity = 1; - break; - } - ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) => { - self.deep_cut_encountered = true; - result.push(term); - } - ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => { - result.push(term) - } - ChunkedTerm::BodyTerm(&QueryTerm::Clause( - _, - ClauseType::CallN(_), - ref subterms, - _, - )) => { - result.push(term); - arity = subterms.len() + 1; - break; - } - ChunkedTerm::BodyTerm(qt) => { - result.push(term); - arity = qt.arity(); - break; - } - }; - - item = self.iter.next(); } - let chunk_num = self.chunk_num; - self.chunk_num += 1; - - (chunk_num, arity, result) + depth } } -impl<'a> Iterator for ChunkedIterator<'a> { - // the chunk number, last term arity, and vector of references. - type Item = ChunkedIteratorItem<'a>; +impl<'a> Iterator for ClauseIterator<'a> { + type Item = ClauseItem<'a>; fn next(&mut self) -> Option { - self.iter.next().map(|term| self.take_chunk(term)) + while let Some(state) = self.state_stack.pop() { + match state { + ClauseIteratorState::RemainingChunks(chunks, focus) if focus < chunks.len() => { + if focus + 1 < chunks.len() { + self.state_stack.push(ClauseIteratorState::RemainingChunks(chunks, focus + 1)); + } else { + self.remaining_chunks_on_stack -= 1; + } + + match &chunks[focus] { + ChunkedTerms::Branch(branches) => { + self.state_stack.push(ClauseIteratorState::RemainingBranches(branches, 0)); + } + ChunkedTerms::Chunk(chunk) => { + return Some(ClauseItem::Chunk(chunk)); + } + } + } + ClauseIteratorState::RemainingChunks(chunks, focus) => { + debug_assert_eq!(chunks.len(), focus); + } + ClauseIteratorState::RemainingBranches(branches, focus) if focus < branches.len() => { + self.state_stack.push(ClauseIteratorState::RemainingBranches(&branches, focus + 1)); + let state = state_from_chunked_terms(&branches[focus]); + + if let ClauseIteratorState::RemainingChunks(..) = &state { + self.remaining_chunks_on_stack += 1; + } + + self.state_stack.push(state); + + return if focus == 0 { + Some(ClauseItem::FirstBranch(branches.len())) + } else { + Some(ClauseItem::NextBranch) + }; + } + ClauseIteratorState::RemainingBranches(branches, focus) => { + debug_assert_eq!(branches.len(), focus); + return Some(ClauseItem::BranchEnd(self.branch_end_depth())); + } + } + } + + None } } diff --git a/src/lib.rs b/src/lib.rs index 45dc2385..36f7a45b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ mod arithmetic; pub mod codegen; mod debray_allocator; mod ffi; -mod fixtures; +mod variable_records; mod forms; mod heap_iter; pub mod heap_print; diff --git a/src/lib/builtins.pl b/src/lib/builtins.pl index 0005d395..1c183a0c 100644 --- a/src/lib/builtins.pl +++ b/src/lib/builtins.pl @@ -218,13 +218,13 @@ fail :- '$fail'. %% \+(Goal) % % True iff Goal fails -\+ G :- call(G), !, false. +\+ G :- call(G), !, '$fail'. \+ _. %% \=(?X, ?Y) % % True iff X and Y can't be unified -X \= X :- !, false. +X \= X :- !, '$fail'. _ \= _. diff --git a/src/lib/format.pl b/src/lib/format.pl index 32ad2ff9..be1cd532 100644 --- a/src/lib/format.pl +++ b/src/lib/format.pl @@ -513,10 +513,12 @@ portray_clause(Stream, Term) :- phrase_to_stream(portray_clause_(Term), Stream), flush_output(Stream). +% called once. portray_clause_(Term) --> { unique_variable_names(Term, VNs) }, portray_(Term, VNs), ".\n". +% mysteriously called twice, the second time with the truncated B3. unique_variable_names(Term, VNs) :- term_variables(Term, Vs), foldl(var_name, Vs, VNs, 0, _). diff --git a/src/lib/iso_ext.pl b/src/lib/iso_ext.pl index f22420af..d6f13df0 100644 --- a/src/lib/iso_ext.pl +++ b/src/lib/iso_ext.pl @@ -175,7 +175,7 @@ scc_helper(_, _, _) :- run_cleaners_with_handling :- '$get_scc_cleaner'(C), - '$get_level'(B), + '$get_cp'(B), catch(C, _, true), '$set_cp_by_default'(B), run_cleaners_with_handling. @@ -186,7 +186,7 @@ run_cleaners_with_handling :- run_cleaners_without_handling(Cp) :- '$get_scc_cleaner'(C), - '$get_level'(B), + '$get_cp'(B), call(C), '$set_cp_by_default'(B), run_cleaners_without_handling(Cp). @@ -258,7 +258,7 @@ call_with_inference_limit(_, _, R, Bb, B) :- '$remove_inference_counter'(B, _), ( '$get_ball'(Ball), '$push_ball_stack', - '$get_level'(Cp), + '$get_cp'(Cp), '$set_cp_by_default'(Cp) ; '$remove_call_policy_check'(B), '$fail' diff --git a/src/loader.pl b/src/loader.pl index 754ed96f..f809cd1a 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -541,6 +541,7 @@ open_file(Path, Stream) :- ) ). + use_module(Module, Exports, Evacuable) :- ( var(Module) -> instantiation_error(load/1) @@ -562,12 +563,11 @@ use_module(Module, Exports, Evacuable) :- stream_property(Stream, file_name(PathFileName)), file_load(Stream, PathFileName, Subevacuable), '$use_module'(Evacuable, Subevacuable, Exports) - ; type_error(atom, Library, load/1) + ; type_error(atom, Module, load/1) ) ). - check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm) :- '$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm). check_predicate_property(built_in, _, Name, Arity, built_in) :- diff --git a/src/machine/code_walker.rs b/src/machine/code_walker.rs index fcda8710..1244eb20 100644 --- a/src/machine/code_walker.rs +++ b/src/machine/code_walker.rs @@ -23,13 +23,9 @@ fn capture_offset(line: &Instruction, index: usize, stack: &mut Vec) -> b { stack.push(index + offset); } - &Instruction::JmpByCall(_, offset, _) => { + &Instruction::JmpByCall(offset) => { stack.push(index + offset); } - &Instruction::JmpByExecute(_, offset, _) => { - stack.push(index + offset); - return true; - } &Instruction::Proceed => { return true; } diff --git a/src/machine/compile.rs b/src/machine/compile.rs index 5f3d8e28..0faf34c3 100644 --- a/src/machine/compile.rs +++ b/src/machine/compile.rs @@ -44,60 +44,6 @@ pub(super) fn bootstrapping_compile( Ok(()) } -// throw errors if declaration or query found. -pub(super) fn compile_relation( - cg: &mut CodeGenerator, - tl: &TopLevel, -) -> Result { - match tl { - &TopLevel::Query(_) => Err(CompilationError::ExpectedRel), - &TopLevel::Predicate(ref clauses) => cg.compile_predicate(&clauses), - &TopLevel::Fact(ref fact, ..) => cg.compile_fact(fact), - &TopLevel::Rule(ref rule, ..) => cg.compile_rule(rule), - } -} - -pub(super) fn compile_appendix( - code: &mut Code, - mut queue: VecDeque, - jmp_by_locs: Vec, - non_counted_bt: bool, - atom_tbl: &mut AtomTable, -) -> Result<(), CompilationError> { - let mut jmp_by_locs = VecDeque::from(jmp_by_locs); - - while let Some(jmp_by_offset) = jmp_by_locs.pop_front() { - let code_len = code.len(); - - match &mut code[jmp_by_offset] { - &mut Instruction::JmpByCall(_, ref mut offset, ..) | - &mut Instruction::JmpByExecute(_, ref mut offset, ..) => { - *offset = code_len - jmp_by_offset; - } - _ => { - unreachable!() - } - } - - // false because the inner predicate is a one-off, hence not extensible. - let settings = CodeGenSettings { - global_clock_tick: None, - is_extensible: false, - non_counted_bt, - }; - - let mut cg = CodeGenerator::new(atom_tbl, settings); - - let tl = queue.pop_front().unwrap(); - let decl_code = compile_relation(&mut cg, &tl)?; - - jmp_by_locs.extend(cg.jmp_by_locs.into_iter().map(|offset| offset + code.len())); - code.extend(decl_code.into_iter()); - } - - Ok(()) -} - fn lower_bound_of_target_clause(skeleton: &PredicateSkeleton, target_pos: usize) -> usize { if target_pos == 0 { return 0; @@ -1342,22 +1288,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { let mut preprocessor = Preprocessor::new(settings); let clause = self.try_term_to_tl(term, &mut preprocessor)?; - let queue = preprocessor.parse_queue(self)?; + // let queue = preprocessor.parse_queue(self)?; let mut cg = CodeGenerator::new( &mut LS::machine_st(&mut self.payload).atom_tbl, settings, ); - let mut clause_code = cg.compile_predicate(&vec![clause])?; - - compile_appendix( - &mut clause_code, - queue, - cg.jmp_by_locs, - settings.non_counted_bt, - cg.atom_tbl, - )?; + let clause_code = cg.compile_predicate(vec![clause])?; Ok(StandaloneCompileResult { clause_code, @@ -1385,22 +1323,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { clauses.push(self.try_term_to_tl(term, &mut preprocessor)?); } - let queue = preprocessor.parse_queue(self)?; - let mut cg = CodeGenerator::new( &mut LS::machine_st(&mut self.payload).atom_tbl, settings, ); - let mut code = cg.compile_predicate(&clauses)?; - - compile_appendix( - &mut code, - queue, - cg.jmp_by_locs, - settings.non_counted_bt, - cg.atom_tbl, - )?; + let mut code = cg.compile_predicate(clauses)?; if settings.is_extensible { let mut clause_clause_locs = VecDeque::new(); diff --git a/src/machine/disjuncts.rs b/src/machine/disjuncts.rs new file mode 100644 index 00000000..3ef2bbf8 --- /dev/null +++ b/src/machine/disjuncts.rs @@ -0,0 +1,829 @@ +use crate::atom_table::*; +use crate::forms::*; +use crate::instructions::*; +use crate::iterators::*; +use crate::machine::loader::*; +use crate::machine::machine_errors::CompilationError; +use crate::machine::preprocessor::*; +use crate::parser::ast::*; +use crate::parser::rug::Rational; +use crate::variable_records::*; + +use indexmap::{IndexMap, IndexSet}; + +use std::cell::Cell; +use std::cmp::Ordering; +use std::collections::VecDeque; +use std::hash::{Hash, Hasher}; +use std::ops::{Deref, DerefMut}; + +#[derive(Debug, Clone)] //, PartialOrd, PartialEq, Eq, Hash)] +pub struct BranchNumber { + branch_num: Rational, + delta: Rational, +} + +impl Default for BranchNumber { + fn default() -> Self { + Self { + branch_num: Rational::from(1usize << 63), + delta: Rational::from(1), + } + } +} + +impl PartialEq for BranchNumber { + #[inline] + fn eq(&self, rhs: &BranchNumber) -> bool { + self.branch_num == rhs.branch_num + } +} + +impl Eq for BranchNumber {} + +impl Hash for BranchNumber { + #[inline(always)] + fn hash(&self, hasher: &mut H) { + self.branch_num.hash(hasher) + } +} + +impl PartialOrd for BranchNumber { + #[inline] + fn partial_cmp(&self, rhs: &BranchNumber) -> Option { + self.branch_num.partial_cmp(&rhs.branch_num) + } +} + +impl BranchNumber { + fn split(&self) -> BranchNumber { + BranchNumber { + branch_num: self.branch_num.clone() + &self.delta / Rational::from(2), + delta: &self.delta / Rational::from(4), + } + } + + fn incr_by_delta(&self) -> BranchNumber { + BranchNumber { + branch_num: self.branch_num.clone() + &self.delta, + delta: self.delta.clone(), + } + } + + fn halve_delta(&self) -> BranchNumber { + BranchNumber { + branch_num: self.branch_num.clone(), + delta : &self.delta / Rational::from(2), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct VarInfo { + var_ptr: VarPtr, + chunk_type: ChunkType, + classify_info: ClassifyInfo, + lvl: Level, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ChunkInfo { + chunk_num: usize, + term_loc: GenContext, + // pointer to incidence, term occurrence arity. + vars: Vec, +} + +#[derive(Debug)] +pub struct BranchArm { + pub arm_terms: Vec, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct BranchInfo { + branch_num: BranchNumber, + chunks: Vec, +} + +impl BranchInfo { + fn new(branch_num: BranchNumber) -> Self { + Self { branch_num, chunks: vec![] } + } +} + +type BranchMapInt = IndexMap>; + +#[derive(Debug, Clone)] +pub struct BranchMap(BranchMapInt); + +impl Deref for BranchMap { + type Target = BranchMapInt; + + #[inline(always)] + fn deref(&self) -> &BranchMapInt { + &self.0 + } +} + +impl DerefMut for BranchMap { + #[inline(always)] + fn deref_mut(&mut self) -> &mut BranchMapInt { + &mut self.0 + } +} + +type RootSet = IndexSet; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ClassifyInfo { + arg_c: usize, + arity: usize, +} + +enum TraversalState { + // construct a QueryTerm::Branch with number of disjuncts, reset + // the chunk type to that of the chunk preceding the disjunct and the chunk_num. + BuildDisjunct(usize), + // add the last disjunct to a QueryTerm::Branch, continuing from + // where it leaves off. + BuildFinalDisjunct(usize), + Fail, + GetCutPoint{ var_num: usize, prev_b: bool }, + Cut { var_num: usize, is_global: bool }, + ResetCallPolicy(CallPolicy), + Term(Term), + RemoveBranchNum, // pop the current_branch_num and from the root set. + AddBranchNum(BranchNumber), // set current_branch_num, add it to the root set + RepBranchNum(BranchNumber), // replace current_branch_num and the latest in the root set + // SetChunkType(ChunkType), // consider remaining terms as belonging to a last chunk +} + +#[derive(Debug)] +pub struct VariableClassifier { + call_policy: CallPolicy, + current_branch_num: BranchNumber, + current_chunk_num: usize, + current_chunk_type: ChunkType, + branch_map: BranchMap, + var_num: usize, + root_set: RootSet, + global_cut_var_num: Option, +} + +#[derive(Debug, Default)] +pub struct VarData { + pub records: VariableRecords, + pub global_cut_var_num: Option, + pub allocates: bool, +} + +impl VarData { + fn emit_initial_get_level(&mut self, build_stack: &mut ChunkedTermVec) { + let global_cut_var_num = + if let &Some(global_cut_var_num) = &self.global_cut_var_num { + match &self.records[global_cut_var_num].allocation { + VarAlloc::Perm(..) => Some(global_cut_var_num), + VarAlloc::Temp { term_loc, .. } if term_loc.chunk_num() > 0 => { + Some(global_cut_var_num) + } + _ => None + } + } else { + None + }; + + if let Some(global_cut_var_num) = global_cut_var_num { + let term = QueryTerm::GetLevel(global_cut_var_num); + self.records[global_cut_var_num].allocation = VarAlloc::Perm(0, PermVarAllocation::Pending); + + match build_stack.front_mut() { + Some(ChunkedTerms::Branch(_)) => { + build_stack.push_front(ChunkedTerms::Chunk(VecDeque::from(vec![term]))); + } + Some(ChunkedTerms::Chunk(chunk)) => { + chunk.push_front(term); + } + None => { + unreachable!() + } + } + } + } +} + +pub type ClassifyFactResult = (Term, VarData); +pub type ClassifyRuleResult = (Term, ChunkedTermVec, VarData); + +fn merge_branch_seq>(branches: Iter) -> BranchInfo { + let mut branch_info = BranchInfo::new(BranchNumber::default()); + + for mut branch in branches { + branch_info.branch_num = branch.branch_num; + + /* + if let Some(last_chunk) = branch_info.chunks.last_mut() { + if let Some(first_moved_chunk) = branch.chunks.first_mut() { + if last_chunk.chunk_num == first_moved_chunk.chunk_num { + last_chunk.vars.extend(first_moved_chunk.vars.drain(..)); + branch_info.chunks.extend(branch.chunks.drain(1 ..)); + + continue; + } + } + } + */ + + branch_info.chunks.extend(branch.chunks.drain(..)); + } + + branch_info.branch_num.delta *= 2; + branch_info.branch_num.branch_num -= &branch_info.branch_num.delta; + + branch_info +} + +fn flatten_into_disjunct(build_stack: &mut ChunkedTermVec, preceding_len: usize) { + let branch_vec = build_stack.drain(preceding_len + 1 ..).collect(); + + if let ChunkedTerms::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] { + disjuncts.push(branch_vec); + } else { + unreachable!(); + } +} + +impl VariableClassifier { + pub fn new(call_policy: CallPolicy) -> Self { + Self { + call_policy, + current_branch_num: BranchNumber::default(), + current_chunk_num: 0, + current_chunk_type: ChunkType::Head, + branch_map: BranchMap(BranchMapInt::new()), + root_set: RootSet::new(), + var_num: 0, + global_cut_var_num: None, + } + } + + pub fn classify_fact(mut self, term: Term) -> Result { + self.classify_head_variables(&term)?; + Ok((term, self.branch_map.separate_and_classify_variables( + self.var_num, + self.global_cut_var_num, + self.current_chunk_num, + ))) + } + + pub fn classify_rule<'a, LS: LoadState<'a>>( + mut self, + loader: &mut Loader<'a, LS>, + head: Term, + body: Term, + ) -> Result { + self.classify_head_variables(&head)?; + self.root_set.insert(self.current_branch_num.clone()); + + let mut query_terms = self.classify_body_variables(loader, body)?; + + self.merge_branches(); + + let mut var_data = self.branch_map.separate_and_classify_variables( + self.var_num, + self.global_cut_var_num, + self.current_chunk_num, + ); + + var_data.emit_initial_get_level(&mut query_terms); + + Ok((head, query_terms, var_data)) + } + + fn merge_branches(&mut self) { + for branches in self.branch_map.values_mut() { + let mut old_branches = std::mem::replace(branches, vec![]); + + while let Some(last_branch_num) = old_branches.last().map(|bi| &bi.branch_num) { + let mut old_branches_len = old_branches.len(); + + for (rev_idx, bi) in old_branches.iter().rev().enumerate() { + if &bi.branch_num > last_branch_num { + old_branches_len = old_branches.len() - rev_idx; + } + } + + let iter = old_branches.drain(old_branches_len - 1 ..); + branches.push(merge_branch_seq(iter)); + } + + branches.reverse(); + } + } + + fn try_set_chunk_at_inlined_boundary(&mut self) -> bool { + if self.current_chunk_type.is_last() { + self.current_chunk_type = ChunkType::Mid; + self.current_chunk_num += 1; + true + } else { + false + } + } + + fn try_set_chunk_at_call_boundary(&mut self) -> bool { + if self.current_chunk_type.is_last() { + self.current_chunk_num += 1; + true + } else { + self.current_chunk_type = ChunkType::Last; + false + } + } + + fn probe_body_term(&mut self, arg_c: usize, arity: usize, term: &Term) { + let classify_info = ClassifyInfo { arg_c, arity }; + + // second arg is true to iterate the root, which may be a variable + for term_ref in breadth_first_iter(term, RootIterationPolicy::Iterated) { + if let TermRef::Var(lvl, _, var_ptr) = term_ref { + // root terms are shallow here (since we're iterating a + // body term) so take the child level. + let lvl = lvl.child_level(); + self.probe_body_var(VarInfo { + var_ptr, + lvl, + classify_info, + chunk_type: self.current_chunk_type, + }); + } + } + } + + fn probe_body_var(&mut self, var_info: VarInfo) { + let term_loc = self.current_chunk_type.to_gen_context(self.current_chunk_num); + + let branch_info_v = self.branch_map.entry(var_info.var_ptr.clone()) + .or_insert_with(|| vec![]); + + let needs_new_branch = if let Some(last_bi) = branch_info_v.last() { + !self.root_set.contains(&last_bi.branch_num) + } else { + true + }; + + if needs_new_branch { + branch_info_v.push(BranchInfo::new(self.current_branch_num.clone())); + } + + let branch_info = branch_info_v.last_mut().unwrap(); + + let needs_new_chunk = if let Some(last_ci) = branch_info.chunks.last() { + last_ci.chunk_num != self.current_chunk_num + } else { + true + }; + + if needs_new_chunk { + branch_info.chunks.push(ChunkInfo { + chunk_num: self.current_chunk_num, + term_loc, + vars: vec![], + }); + } + + let chunk_info = branch_info.chunks.last_mut().unwrap(); + chunk_info.vars.push(var_info); + } + + fn probe_in_situ_var(&mut self, var_num: usize) { + let classify_info = ClassifyInfo { arg_c: 1, arity: 1 }; + + let var_info = VarInfo { + var_ptr: VarPtr::from(Var::InSitu(var_num)), + classify_info, + chunk_type: self.current_chunk_type, + lvl: Level::Shallow, + }; + + self.probe_body_var(var_info); + } + + fn classify_head_variables(&mut self, term: &Term) -> Result<(), CompilationError> { + match term { + Term::Clause(..) | Term::Literal(_, Literal::Atom(_)) => { + } + _ => return Err(CompilationError::InvalidRuleHead), + } + + let mut classify_info = ClassifyInfo { arg_c: 1, arity: term.arity() }; + + match term { + Term::Clause(_, _, terms) => { + for term in terms.into_iter() { + for term_ref in breadth_first_iter(term, RootIterationPolicy::Iterated) { + if let TermRef::Var(lvl, _, var_ptr) = term_ref { + // a body term, so we need the child level here. + let lvl = lvl.child_level(); + + // the body of the if let here is an inlined + // "probe_head_var". note the difference between it + // and "probe_body_var". + let branch_info_v = self.branch_map.entry(var_ptr.clone()) + .or_insert_with(|| vec![]); + + let needs_new_branch = branch_info_v.is_empty(); + + if needs_new_branch { + branch_info_v.push(BranchInfo::new(self.current_branch_num.clone())); + } + + 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(()) + } + + fn classify_body_variables<'a, LS: LoadState<'a>>( + &mut self, + loader: &mut Loader<'a, LS>, + term: Term, + ) -> Result { + let mut state_stack = vec![TraversalState::Term(term)]; + let mut build_stack = ChunkedTermVec::new(); + + self.current_chunk_type = ChunkType::Mid; + + while let Some(traversal_st) = state_stack.pop() { + match traversal_st { + TraversalState::AddBranchNum(branch_num) => { + self.root_set.insert(branch_num.clone()); + self.current_branch_num = branch_num; + } + TraversalState::RemoveBranchNum => { + self.root_set.pop(); + } + TraversalState::RepBranchNum(branch_num) => { + self.root_set.pop(); + self.root_set.insert(branch_num.clone()); + self.current_branch_num = branch_num; + } + TraversalState::ResetCallPolicy(call_policy) => { + self.call_policy = call_policy; + } + TraversalState::BuildDisjunct(preceding_len) => { + flatten_into_disjunct(&mut build_stack, preceding_len); + + self.current_chunk_type = ChunkType::Mid; + self.current_chunk_num += 1; + } + TraversalState::BuildFinalDisjunct(preceding_len) => { + flatten_into_disjunct(&mut build_stack, preceding_len); + + self.current_chunk_type = ChunkType::Mid; + self.current_chunk_num += 1; + } + TraversalState::GetCutPoint { var_num, prev_b } => { + if self.try_set_chunk_at_inlined_boundary() { + build_stack.add_chunk(); + } + + self.probe_in_situ_var(var_num); + build_stack.push_chunk_term(QueryTerm::GetCutPoint { var_num, prev_b }); + } + TraversalState::Cut { var_num, is_global } => { + if self.try_set_chunk_at_inlined_boundary() { + build_stack.add_chunk(); + } + + self.probe_in_situ_var(var_num); + + build_stack.push_chunk_term( + if is_global { + QueryTerm::GlobalCut(var_num) + } else { + QueryTerm::LocalCut(var_num) + } + ); + } + TraversalState::Fail => { + build_stack.push_chunk_term(QueryTerm::Fail); + } + TraversalState::Term(term) => { + // return true iff new chunk should be added. + let update_chunk_data = |classifier: &mut Self, predicate_name, arity| { + if ClauseType::is_inlined(predicate_name, arity) { + classifier.try_set_chunk_at_inlined_boundary() + } else { + classifier.try_set_chunk_at_call_boundary() + } + }; + + match term { + Term::Clause(_, atom!(","), mut terms) if terms.len() == 2 => { + let tail = terms.pop().unwrap(); + let head = terms.pop().unwrap(); + + let iter = unfold_by_str(tail, atom!(",")) + .into_iter() + .rev() + .chain(std::iter::once(head)) + .map(TraversalState::Term); + + state_stack.extend(iter); + } + Term::Clause(_, atom!(";"), mut terms) if terms.len() == 2 => { + let tail = terms.pop().unwrap(); + let head = terms.pop().unwrap(); + + let first_branch_num = self.current_branch_num.split(); + let branches: Vec<_> = std::iter::once(head) + .chain(unfold_by_str(tail, atom!(";")).into_iter()) + .collect(); + + let mut branch_numbers = vec![first_branch_num]; + + for idx in 1 .. branches.len() { + let succ_branch_number = branch_numbers[idx - 1].incr_by_delta(); + + branch_numbers.push(if idx + 1 < branches.len() { + succ_branch_number.split() + } else { + succ_branch_number + }); + } + + let build_stack_len = build_stack.len(); + build_stack.reserve_branch(branches.len()); + + state_stack.push(TraversalState::RepBranchNum( + self.current_branch_num.halve_delta(), + )); + + let iter = branches.into_iter().zip(branch_numbers.into_iter()); + let final_disjunct_loc = state_stack.len(); + + for (term, branch_num) in iter.rev() { + state_stack.push(TraversalState::BuildDisjunct(build_stack_len)); + state_stack.push(TraversalState::RemoveBranchNum); + state_stack.push(TraversalState::Term(term)); + state_stack.push(TraversalState::AddBranchNum(branch_num)); + } + + if let TraversalState::BuildDisjunct(build_stack_len) = state_stack[final_disjunct_loc] { + state_stack[final_disjunct_loc] = TraversalState::BuildFinalDisjunct(build_stack_len); + } + } + Term::Clause(_, atom!("->"), mut terms) if terms.len() == 2 => { + let then_term = terms.pop().unwrap(); + let if_term = terms.pop().unwrap(); + + let prev_b = if matches!(state_stack.last(), Some(TraversalState::RemoveBranchNum)) { + // check if the second-to-last element is a regular BuildDisjunct, as we don't + // want to add GetPrevLevel in case of a TrustMe. + matches!(state_stack.iter().rev().nth(1), Some(TraversalState::BuildDisjunct(..))) + } else { + false + }; + + state_stack.push(TraversalState::Term(then_term)); + state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false }); + state_stack.push(TraversalState::Term(if_term)); + state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b }); + + self.var_num += 1; + } + Term::Clause(_, atom!("\\+"), mut terms) if terms.len() == 1 => { + let not_term = terms.pop().unwrap(); + let build_stack_len = build_stack.len(); + + build_stack.reserve_branch(2); + + state_stack.push(TraversalState::BuildFinalDisjunct(build_stack_len)); + state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), atom!("$succeed"), vec![]))); + state_stack.push(TraversalState::BuildDisjunct(build_stack_len)); + state_stack.push(TraversalState::Fail); + state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false }); + state_stack.push(TraversalState::Term(not_term)); + state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b: true }); + + self.var_num += 1; + } + Term::Clause(_, atom!(":"), mut terms) if terms.len() == 2 => { + let predicate_name = terms.pop().unwrap(); + let module_name = terms.pop().unwrap(); + + match (module_name, predicate_name) { + ( + Term::Literal(_, Literal::Atom(module_name)), + Term::Literal(_, Literal::Atom(predicate_name)), + ) => { + if update_chunk_data(self, predicate_name, 0) { + build_stack.add_chunk(); + } + + build_stack.push_chunk_term( + qualified_clause_to_query_term( + loader, + module_name, + predicate_name, + vec![], + self.call_policy, + ), + ); + } + ( + Term::Literal(_, Literal::Atom(module_name)), + Term::Clause(_, name, terms), + ) => { + if update_chunk_data(self, name, terms.len()) { + build_stack.add_chunk(); + } + + for (arg_c, term) in terms.iter().enumerate() { + self.probe_body_term(arg_c + 1, terms.len(), term); + } + + build_stack.push_chunk_term( + qualified_clause_to_query_term( + loader, + module_name, + name, + terms, + self.call_policy, + ), + ); + } + (module_name, predicate_name) => { + if update_chunk_data(self, atom!("call"), 2) { + build_stack.add_chunk(); + } + + self.probe_body_term(1, 0, &module_name); + self.probe_body_term(2, 0, &predicate_name); + + terms.push(module_name); + terms.push(predicate_name); + + build_stack.push_chunk_term( + clause_to_query_term( + loader, + atom!("call"), + vec![Term::Clause(Cell::default(), atom!(":"), terms)], + self.call_policy, + ), + ); + } + } + } + Term::Clause(_, atom!("$call_with_inference_counting"), mut terms) if terms.len() == 1 => { + state_stack.push(TraversalState::ResetCallPolicy(self.call_policy)); + state_stack.push(TraversalState::Term(terms.pop().unwrap())); + + self.call_policy = CallPolicy::Counted; + } + Term::Clause(_, name, terms) => { + if update_chunk_data(self, name, terms.len()) { + build_stack.add_chunk(); + } + + for (arg_c, term) in terms.iter().enumerate() { + self.probe_body_term(arg_c + 1, terms.len(), term); + } + + build_stack.push_chunk_term( + clause_to_query_term( + loader, + name, + terms, + self.call_policy, + ), + ); + } + Term::Literal(_, Literal::Atom(atom!("!")) | Literal::Char('!')) => { + if self.global_cut_var_num.is_none() { + self.global_cut_var_num = Some(self.var_num); + self.var_num += 1; + } + + self.probe_in_situ_var(self.global_cut_var_num.unwrap()); + + state_stack.push(TraversalState::Cut { + var_num: self.global_cut_var_num.unwrap(), + is_global: true, + }); + } + Term::Literal(_, Literal::Atom(name)) => { + if update_chunk_data(self, name, 0) { + build_stack.add_chunk(); + } + + build_stack.push_chunk_term( + clause_to_query_term( + loader, + name, + vec![], + self.call_policy, + ), + ); + } + _ => { + return Err(CompilationError::InadmissibleQueryTerm); + } + } + } + } + } + + Ok(build_stack) + } +} + +impl BranchMap { + pub fn separate_and_classify_variables( + &mut self, + var_num: usize, + global_cut_var_num: Option, + current_chunk_num: usize, + ) -> VarData { + let mut var_data = VarData { + records: VariableRecords::new(var_num), + global_cut_var_num, + allocates: current_chunk_num > 0, + }; + + for (var, branches) in self.iter_mut() { + let (mut var_num, var_num_incr) = + if let Var::InSitu(var_num) = *var.borrow() { + (var_num, false) + } else { + (var_data.records.len(), true) + }; + + for branch in branches.iter_mut() { + if var_num_incr { + var_num = var_data.records.len(); + var_data.records.push(VariableRecord::default()); + } + + if branch.chunks.len() <= 1 { // true iff var is a temporary variable. + debug_assert_eq!(branch.chunks.len(), 1); + + let chunk = &mut branch.chunks[0]; + let mut temp_var_data = TempVarData::new(); + + for var_info in chunk.vars.iter_mut() { + if var_info.lvl == Level::Shallow { + let term_loc = var_info.chunk_type.to_gen_context(chunk.chunk_num); + temp_var_data.use_set.insert((term_loc, var_info.classify_info.arg_c)); + } + } + + var_data.records[var_num].allocation = VarAlloc::Temp { + term_loc: chunk.term_loc, + temp_reg: 0, + temp_var_data, + safety: VarSafetyStatus::Needed, + to_perm_var_num: None, + }; + } // else VarAlloc is already a Perm variant, as it's the default. + + for chunk in branch.chunks.iter_mut() { + var_data.records[var_num].num_occurrences += chunk.vars.len(); + + for var_info in chunk.vars.iter_mut() { + var_info.var_ptr.set(Var::Generated(var_num)); + } + } + } + } + + var_data.records.populate_restricting_sets(); + var_data + } +} diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 65c82e48..686ec71b 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -1152,16 +1152,15 @@ impl Machine { self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(b0 as i64)); self.machine_st.p += 1; } - &Instruction::GetLevelAndUnify(r) => { - // let b0 = self.machine_st[perm_v!(1)]; - let b0 = cell_as_fixnum!( - self.machine_st.stack[stack_loc!(AndFrame, self.machine_st.e, 1)] - ); - let a = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); + &Instruction::GetPrevLevel(r) => { + let prev_b = self.machine_st.stack.index_or_frame(self.machine_st.b).prelude.b; - // unify_fn!(&mut self.machine_st, a, b0); - self.machine_st.unify_fixnum(b0, a); - step_or_fail!(self, self.machine_st.p += 1); + self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(prev_b as i64)); + self.machine_st.p += 1; + } + &Instruction::GetCutPoint(r) => { + self.machine_st[r] = fixnum_as_cell!(Fixnum::build_with(self.machine_st.b as i64)); + self.machine_st.p += 1; } &Instruction::Cut(r) => { let value = self.machine_st[r]; @@ -1181,7 +1180,7 @@ impl Machine { &Instruction::Allocate(num_cells) => { self.machine_st.allocate(num_cells); } - &Instruction::DefaultCallAcyclicTerm(_) => { + &Instruction::DefaultCallAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1190,7 +1189,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteAcyclicTerm(_) => { + &Instruction::DefaultExecuteAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1199,23 +1198,23 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallArg(_) => { + &Instruction::DefaultCallArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteArg(_) => { + &Instruction::DefaultExecuteArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::DefaultCallCompare(_) => { + &Instruction::DefaultCallCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteCompare(_) => { + &Instruction::DefaultExecuteCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::DefaultCallTermGreaterThan(_) => { + &Instruction::DefaultCallTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1225,7 +1224,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteTermGreaterThan(_) => { + &Instruction::DefaultExecuteTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1235,7 +1234,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultCallTermLessThan(_) => { + &Instruction::DefaultCallTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1245,7 +1244,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteTermLessThan(_) => { + &Instruction::DefaultExecuteTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1255,7 +1254,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultCallTermGreaterThanOrEqual(_) => { + &Instruction::DefaultCallTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1268,7 +1267,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteTermGreaterThanOrEqual(_) => { + &Instruction::DefaultExecuteTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1281,7 +1280,7 @@ impl Machine { } } } - &Instruction::DefaultCallTermLessThanOrEqual(_) => { + &Instruction::DefaultCallTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1294,7 +1293,7 @@ impl Machine { } } } - &Instruction::DefaultExecuteTermLessThanOrEqual(_) => { + &Instruction::DefaultExecuteTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1307,11 +1306,11 @@ impl Machine { } } } - &Instruction::DefaultCallRead(_) => { + &Instruction::DefaultCallRead => { try_or_throw!(self.machine_st, self.read()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteRead(_) => { + &Instruction::DefaultExecuteRead => { try_or_throw!(self.machine_st, self.read()); if self.machine_st.fail { @@ -1320,11 +1319,11 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallCopyTerm(_) => { + &Instruction::DefaultCallCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteCopyTerm(_) => { + &Instruction::DefaultExecuteCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); if self.machine_st.fail { @@ -1333,7 +1332,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallTermEqual(_) => { + &Instruction::DefaultCallTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1343,7 +1342,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteTermEqual(_) => { + &Instruction::DefaultExecuteTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1353,26 +1352,26 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallGround(_) => { + &Instruction::DefaultCallGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteGround(_) => { + &Instruction::DefaultExecuteGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallFunctor(_) => { + &Instruction::DefaultCallFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteFunctor(_) => { + &Instruction::DefaultExecuteFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); if self.machine_st.fail { @@ -1381,7 +1380,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallTermNotEqual(_) => { + &Instruction::DefaultCallTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1391,7 +1390,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::DefaultExecuteTermNotEqual(_) => { + &Instruction::DefaultExecuteTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1401,19 +1400,19 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallSort(_) => { + &Instruction::DefaultCallSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteSort(_) => { + &Instruction::DefaultExecuteSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::DefaultCallKeySort(_) => { + &Instruction::DefaultCallKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteKeySort(_) => { + &Instruction::DefaultExecuteKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); if self.machine_st.fail { @@ -1422,15 +1421,15 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::DefaultCallIs(r, at, _) => { + &Instruction::DefaultCallIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::DefaultExecuteIs(r, at, _) => { + &Instruction::DefaultExecuteIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallAcyclicTerm(_) => { + &Instruction::CallAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1444,7 +1443,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteAcyclicTerm(_) => { + &Instruction::ExecuteAcyclicTerm => { let addr = self.machine_st.registers[1]; if self.machine_st.is_cyclic_term(addr) { @@ -1458,7 +1457,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallArg(_) => { + &Instruction::CallArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); if self.machine_st.fail { @@ -1472,7 +1471,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteArg(_) => { + &Instruction::ExecuteArg => { try_or_throw!(self.machine_st, self.machine_st.try_arg()); if self.machine_st.fail { @@ -1486,7 +1485,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallCompare(_) => { + &Instruction::CallCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); if self.machine_st.fail { @@ -1500,7 +1499,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteCompare(_) => { + &Instruction::ExecuteCompare => { try_or_throw!(self.machine_st, self.machine_st.compare()); if self.machine_st.fail { @@ -1514,7 +1513,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallTermGreaterThan(_) => { + &Instruction::CallTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1529,7 +1528,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::ExecuteTermGreaterThan(_) => { + &Instruction::ExecuteTermGreaterThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1544,7 +1543,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallTermLessThan(_) => { + &Instruction::CallTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1559,7 +1558,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::ExecuteTermLessThan(_) => { + &Instruction::ExecuteTermLessThan => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1574,7 +1573,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallTermGreaterThanOrEqual(_) => { + &Instruction::CallTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1592,7 +1591,7 @@ impl Machine { } } } - &Instruction::ExecuteTermGreaterThanOrEqual(_) => { + &Instruction::ExecuteTermGreaterThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1610,7 +1609,7 @@ impl Machine { } } } - &Instruction::CallTermLessThanOrEqual(_) => { + &Instruction::CallTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1628,7 +1627,7 @@ impl Machine { } } } - &Instruction::ExecuteTermLessThanOrEqual(_) => { + &Instruction::ExecuteTermLessThanOrEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1646,7 +1645,7 @@ impl Machine { } } } - &Instruction::CallRead(_) => { + &Instruction::CallRead => { try_or_throw!(self.machine_st, self.read()); if self.machine_st.fail { @@ -1660,7 +1659,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteRead(_) => { + &Instruction::ExecuteRead => { try_or_throw!(self.machine_st, self.read()); if self.machine_st.fail { @@ -1674,7 +1673,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallCopyTerm(_) => { + &Instruction::CallCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); if self.machine_st.fail { @@ -1688,7 +1687,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteCopyTerm(_) => { + &Instruction::ExecuteCopyTerm => { self.machine_st.copy_term(AttrVarPolicy::DeepCopy); if self.machine_st.fail { @@ -1702,7 +1701,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallTermEqual(_) => { + &Instruction::CallTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1717,7 +1716,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteTermEqual(_) => { + &Instruction::ExecuteTermEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1732,7 +1731,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallGround(_) => { + &Instruction::CallGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { @@ -1744,7 +1743,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteGround(_) => { + &Instruction::ExecuteGround => { if self.machine_st.ground_test() { self.machine_st.backtrack(); } else { @@ -1756,7 +1755,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallFunctor(_) => { + &Instruction::CallFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); if self.machine_st.fail { @@ -1770,7 +1769,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteFunctor(_) => { + &Instruction::ExecuteFunctor => { try_or_throw!(self.machine_st, self.machine_st.try_functor()); if self.machine_st.fail { @@ -1784,7 +1783,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallTermNotEqual(_) => { + &Instruction::CallTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1799,7 +1798,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteTermNotEqual(_) => { + &Instruction::ExecuteTermNotEqual => { let a1 = self.machine_st.registers[1]; let a2 = self.machine_st.registers[2]; @@ -1814,7 +1813,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallSort(_) => { + &Instruction::CallSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); if self.machine_st.fail { @@ -1828,7 +1827,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteSort(_) => { + &Instruction::ExecuteSort => { try_or_throw!(self.machine_st, self.machine_st.sort()); if self.machine_st.fail { @@ -1842,7 +1841,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallKeySort(_) => { + &Instruction::CallKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); if self.machine_st.fail { @@ -1856,7 +1855,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteKeySort(_) => { + &Instruction::ExecuteKeySort => { try_or_throw!(self.machine_st, self.machine_st.keysort()); if self.machine_st.fail { @@ -1870,7 +1869,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallIs(r, at, _) => { + &Instruction::CallIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); if self.machine_st.fail { @@ -1884,7 +1883,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteIs(r, at, _) => { + &Instruction::ExecuteIs(r, at) => { try_or_throw!(self.machine_st, self.machine_st.is(r, at)); if self.machine_st.fail { @@ -1898,7 +1897,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallN(arity, _) => { + &Instruction::CallN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1921,7 +1920,7 @@ impl Machine { ); } } - &Instruction::ExecuteN(arity, _) => { + &Instruction::ExecuteN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1944,7 +1943,7 @@ impl Machine { ); } } - &Instruction::DefaultCallN(arity, _) => { + &Instruction::DefaultCallN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1962,7 +1961,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteN(arity, _) => { + &Instruction::DefaultExecuteN(arity) => { let pred = self.machine_st.registers[1]; for i in 2..arity + 1 { @@ -1980,7 +1979,7 @@ impl Machine { 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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -1998,7 +1997,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2016,7 +2015,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2034,7 +2033,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2052,7 +2051,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2070,7 +2069,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2088,7 +2087,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2106,7 +2105,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2124,7 +2123,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2142,7 +2141,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2160,7 +2159,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2178,7 +2177,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2196,7 +2195,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2209,7 +2208,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2222,7 +2221,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2235,7 +2234,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2248,7 +2247,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2261,7 +2260,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2274,7 +2273,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2287,7 +2286,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2300,7 +2299,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2313,7 +2312,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2326,7 +2325,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2339,7 +2338,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 n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2)); @@ -2353,7 +2352,7 @@ impl Machine { } } // - &Instruction::CallIsAtom(r, _) => { + &Instruction::CallIsAtom(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2382,7 +2381,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsAtom(r, _) => { + &Instruction::ExecuteIsAtom(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2411,7 +2410,7 @@ impl Machine { } ); } - &Instruction::CallIsAtomic(r, _) => { + &Instruction::CallIsAtomic(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2441,7 +2440,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsAtomic(r, _) => { + &Instruction::ExecuteIsAtomic(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2471,7 +2470,7 @@ impl Machine { } ); } - &Instruction::CallIsCompound(r, _) => { + &Instruction::CallIsCompound(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2502,7 +2501,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsCompound(r, _) => { + &Instruction::ExecuteIsCompound(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2533,7 +2532,7 @@ impl Machine { } ); } - &Instruction::CallIsInteger(r, _) => { + &Instruction::CallIsInteger(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2552,7 +2551,7 @@ impl Machine { } } } - &Instruction::ExecuteIsInteger(r, _) => { + &Instruction::ExecuteIsInteger(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2571,7 +2570,7 @@ impl Machine { } } } - &Instruction::CallIsNumber(r, _) => { + &Instruction::CallIsNumber(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2583,7 +2582,7 @@ impl Machine { } } } - &Instruction::ExecuteIsNumber(r, _) => { + &Instruction::ExecuteIsNumber(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2595,7 +2594,7 @@ impl Machine { } } } - &Instruction::CallIsRational(r, _) => { + &Instruction::CallIsRational(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2617,7 +2616,7 @@ impl Machine { } ); } - &Instruction::ExecuteIsRational(r, _) => { + &Instruction::ExecuteIsRational(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); read_heap_cell!(d, @@ -2639,7 +2638,7 @@ impl Machine { } ); } - &Instruction::CallIsFloat(r, _) => { + &Instruction::CallIsFloat(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2651,7 +2650,7 @@ impl Machine { } } } - &Instruction::ExecuteIsFloat(r, _) => { + &Instruction::ExecuteIsFloat(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match Number::try_from(d) { @@ -2663,7 +2662,7 @@ impl Machine { } } } - &Instruction::CallIsNonVar(r, _) => { + &Instruction::CallIsNonVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2677,7 +2676,7 @@ impl Machine { } } } - &Instruction::ExecuteIsNonVar(r, _) => { + &Instruction::ExecuteIsNonVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2691,7 +2690,7 @@ impl Machine { } } } - &Instruction::CallIsVar(r, _) => { + &Instruction::CallIsVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2705,7 +2704,7 @@ impl Machine { } } } - &Instruction::ExecuteIsVar(r, _) => { + &Instruction::ExecuteIsVar(r) => { let d = self.machine_st.store(self.machine_st.deref(self.machine_st[r])); match d.get_tag() { @@ -2719,7 +2718,7 @@ impl Machine { } } } - &Instruction::CallNamed(arity, name, ref idx, _) => { + &Instruction::CallNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2736,7 +2735,7 @@ impl Machine { ); } } - &Instruction::ExecuteNamed(arity, name, ref idx, _) => { + &Instruction::ExecuteNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2753,7 +2752,7 @@ impl Machine { ); } } - &Instruction::DefaultCallNamed(arity, name, ref idx, _) => { + &Instruction::DefaultCallNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2765,7 +2764,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::DefaultExecuteNamed(arity, name, ref idx, _) => { + &Instruction::DefaultExecuteNamed(arity, name, ref idx) => { let idx = idx.get(); try_or_throw!( @@ -2780,15 +2779,7 @@ impl Machine { &Instruction::Deallocate => { self.machine_st.deallocate() } - &Instruction::JmpByCall(arity, offset, _) => { - self.machine_st.num_of_args = arity; - self.machine_st.b0 = self.machine_st.b; - self.machine_st.cp = self.machine_st.p + 1; - self.machine_st.p += offset; - } - &Instruction::JmpByExecute(arity, offset, _) => { - self.machine_st.num_of_args = arity; - self.machine_st.b0 = self.machine_st.b; + &Instruction::JmpByCall(offset) => { self.machine_st.p += offset; } &Instruction::RevJmpBy(offset) => { @@ -3236,8 +3227,8 @@ impl Machine { self.machine_st.p += 1; } - &Instruction::PutUnsafeValue(n, arg) => { - let s = stack_loc!(AndFrame, self.machine_st.e, n); + &Instruction::PutUnsafeValue(perm_slot, arg) => { + let s = stack_loc!(AndFrame, self.machine_st.e, perm_slot); let addr = self.machine_st.store(self.machine_st.deref(stack_loc_as_cell!(s))); if addr.is_protected(self.machine_st.e) { @@ -3315,11 +3306,11 @@ impl Machine { self.machine_st.p += 1; } // - &Instruction::CallAtomChars(_) => { + &Instruction::CallAtomChars => { self.atom_chars(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteAtomChars(_) => { + &Instruction::ExecuteAtomChars => { self.atom_chars(); if self.machine_st.fail { @@ -3328,7 +3319,7 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallAtomCodes(_) => { + &Instruction::CallAtomCodes => { try_or_throw!(self.machine_st, self.atom_codes()); if self.machine_st.fail { @@ -3337,7 +3328,7 @@ impl Machine { self.machine_st.p += 1; } } - &Instruction::ExecuteAtomCodes(_) => { + &Instruction::ExecuteAtomCodes => { try_or_throw!(self.machine_st, self.atom_codes()); if self.machine_st.fail { @@ -3346,237 +3337,237 @@ impl Machine { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallAtomLength(_) => { + &Instruction::CallAtomLength => { self.atom_length(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteAtomLength(_) => { + &Instruction::ExecuteAtomLength => { self.atom_length(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallBindFromRegister(_) => { + &Instruction::CallBindFromRegister => { self.bind_from_register(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteBindFromRegister(_) => { + &Instruction::ExecuteBindFromRegister => { self.bind_from_register(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallContinuation(_) => { + &Instruction::CallContinuation => { try_or_throw!(self.machine_st, self.call_continuation(false)); } - &Instruction::ExecuteContinuation(_) => { + &Instruction::ExecuteContinuation => { try_or_throw!(self.machine_st, self.call_continuation(true)); } - &Instruction::CallCharCode(_) => { + &Instruction::CallCharCode => { try_or_throw!(self.machine_st, self.char_code()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharCode(_) => { + &Instruction::ExecuteCharCode => { try_or_throw!(self.machine_st, self.char_code()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCharType(_) => { + &Instruction::CallCharType => { self.char_type(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharType(_) => { + &Instruction::ExecuteCharType => { self.char_type(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCharsToNumber(_) => { + &Instruction::CallCharsToNumber => { try_or_throw!(self.machine_st, self.chars_to_number()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharsToNumber(_) => { + &Instruction::ExecuteCharsToNumber => { try_or_throw!(self.machine_st, self.chars_to_number()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCodesToNumber(_) => { + &Instruction::CallCodesToNumber => { try_or_throw!(self.machine_st, self.codes_to_number()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCodesToNumber(_) => { + &Instruction::ExecuteCodesToNumber => { try_or_throw!(self.machine_st, self.codes_to_number()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCopyTermWithoutAttrVars(_) => { + &Instruction::CallCopyTermWithoutAttrVars => { self.copy_term_without_attr_vars(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCopyTermWithoutAttrVars(_) => { + &Instruction::ExecuteCopyTermWithoutAttrVars => { self.copy_term_without_attr_vars(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCheckCutPoint(_) => { + &Instruction::CallCheckCutPoint => { self.check_cut_point(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCheckCutPoint(_) => { + &Instruction::ExecuteCheckCutPoint => { self.check_cut_point(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallClose(_) => { + &Instruction::CallClose => { try_or_throw!(self.machine_st, self.close()); self.machine_st.p += 1; } - &Instruction::ExecuteClose(_) => { + &Instruction::ExecuteClose => { try_or_throw!(self.machine_st, self.close()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallCopyToLiftedHeap(_) => { + &Instruction::CallCopyToLiftedHeap => { self.copy_to_lifted_heap(); self.machine_st.p += 1; } - &Instruction::ExecuteCopyToLiftedHeap(_) => { + &Instruction::ExecuteCopyToLiftedHeap => { self.copy_to_lifted_heap(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallCreatePartialString(_) => { + &Instruction::CallCreatePartialString => { self.create_partial_string(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCreatePartialString(_) => { + &Instruction::ExecuteCreatePartialString => { self.create_partial_string(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentHostname(_) => { + &Instruction::CallCurrentHostname => { self.current_hostname(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentHostname(_) => { + &Instruction::ExecuteCurrentHostname => { self.current_hostname(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentInput(_) => { + &Instruction::CallCurrentInput => { try_or_throw!(self.machine_st, self.current_input()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentInput(_) => { + &Instruction::ExecuteCurrentInput => { try_or_throw!(self.machine_st, self.current_input()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentOutput(_) => { + &Instruction::CallCurrentOutput => { try_or_throw!(self.machine_st, self.current_output()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentOutput(_) => { + &Instruction::ExecuteCurrentOutput => { try_or_throw!(self.machine_st, self.current_output()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDirectoryFiles(_) => { + &Instruction::CallDirectoryFiles => { try_or_throw!(self.machine_st, self.directory_files()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDirectoryFiles(_) => { + &Instruction::ExecuteDirectoryFiles => { try_or_throw!(self.machine_st, self.directory_files()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileSize(_) => { + &Instruction::CallFileSize => { self.file_size(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileSize(_) => { + &Instruction::ExecuteFileSize => { self.file_size(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileExists(_) => { + &Instruction::CallFileExists => { self.file_exists(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileExists(_) => { + &Instruction::ExecuteFileExists => { self.file_exists(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDirectoryExists(_) => { + &Instruction::CallDirectoryExists => { self.directory_exists(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDirectoryExists(_) => { + &Instruction::ExecuteDirectoryExists => { self.directory_exists(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDirectorySeparator(_) => { + &Instruction::CallDirectorySeparator => { self.directory_separator(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDirectorySeparator(_) => { + &Instruction::ExecuteDirectorySeparator => { self.directory_separator(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMakeDirectory(_) => { + &Instruction::CallMakeDirectory => { self.make_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMakeDirectory(_) => { + &Instruction::ExecuteMakeDirectory => { self.make_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMakeDirectoryPath(_) => { + &Instruction::CallMakeDirectoryPath => { self.make_directory_path(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMakeDirectoryPath(_) => { + &Instruction::ExecuteMakeDirectoryPath => { self.make_directory_path(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteFile(_) => { + &Instruction::CallDeleteFile => { self.delete_file(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeleteFile(_) => { + &Instruction::ExecuteDeleteFile => { self.delete_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallRenameFile(_) => { + &Instruction::CallRenameFile => { self.rename_file(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteRenameFile(_) => { + &Instruction::ExecuteRenameFile => { self.rename_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileCopy(_) => { + &Instruction::CallFileCopy => { self.file_copy(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileCopy(_) => { + &Instruction::ExecuteFileCopy => { self.file_copy(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallWorkingDirectory(_) => { + &Instruction::CallWorkingDirectory => { try_or_throw!(self.machine_st, self.working_directory()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWorkingDirectory(_) => { + &Instruction::ExecuteWorkingDirectory => { try_or_throw!(self.machine_st, self.working_directory()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteDirectory(_) => { + &Instruction::CallDeleteDirectory => { self.delete_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeleteDirectory(_) => { + &Instruction::ExecuteDeleteDirectory => { self.delete_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPathCanonical(_) => { + &Instruction::CallPathCanonical => { try_or_throw!(self.machine_st, self.path_canonical()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePathCanonical(_) => { + &Instruction::ExecutePathCanonical => { try_or_throw!(self.machine_st, self.path_canonical()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFileTime(_) => { + &Instruction::CallFileTime => { self.file_time(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFileTime(_) => { + &Instruction::ExecuteFileTime => { self.file_time(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDynamicModuleResolution(arity, _) => { + &Instruction::CallDynamicModuleResolution(arity) => { let (module_name, key) = try_or_throw!( self.machine_st, self.dynamic_module_resolution(arity - 2) @@ -3591,7 +3582,7 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::ExecuteDynamicModuleResolution(arity, _) => { + &Instruction::ExecuteDynamicModuleResolution(arity) => { let (module_name, key) = try_or_throw!( self.machine_st, self.dynamic_module_resolution(arity - 2) @@ -3606,428 +3597,428 @@ impl Machine { self.machine_st.backtrack(); } } - &Instruction::CallFetchGlobalVar(_) => { + &Instruction::CallFetchGlobalVar => { self.fetch_global_var(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFetchGlobalVar(_) => { + &Instruction::ExecuteFetchGlobalVar => { self.fetch_global_var(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFirstStream(_) => { + &Instruction::CallFirstStream => { self.first_stream(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFirstStream(_) => { + &Instruction::ExecuteFirstStream => { self.first_stream(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFlushOutput(_) => { + &Instruction::CallFlushOutput => { try_or_throw!(self.machine_st, self.flush_output()); self.machine_st.p += 1; } - &Instruction::ExecuteFlushOutput(_) => { + &Instruction::ExecuteFlushOutput => { try_or_throw!(self.machine_st, self.flush_output()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallGetByte(_) => { + &Instruction::CallGetByte => { try_or_throw!(self.machine_st, self.get_byte()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetByte(_) => { + &Instruction::ExecuteGetByte => { try_or_throw!(self.machine_st, self.get_byte()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetChar(_) => { + &Instruction::CallGetChar => { try_or_throw!(self.machine_st, self.get_char()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetChar(_) => { + &Instruction::ExecuteGetChar => { try_or_throw!(self.machine_st, self.get_char()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetNChars(_) => { + &Instruction::CallGetNChars => { try_or_throw!(self.machine_st, self.get_n_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetNChars(_) => { + &Instruction::ExecuteGetNChars => { try_or_throw!(self.machine_st, self.get_n_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetCode(_) => { + &Instruction::CallGetCode => { try_or_throw!(self.machine_st, self.get_code()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetCode(_) => { + &Instruction::ExecuteGetCode => { try_or_throw!(self.machine_st, self.get_code()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetSingleChar(_) => { + &Instruction::CallGetSingleChar => { try_or_throw!(self.machine_st, self.get_single_char()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetSingleChar(_) => { + &Instruction::ExecuteGetSingleChar => { try_or_throw!(self.machine_st, self.get_single_char()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff(_) => { + &Instruction::CallTruncateIfNoLiftedHeapGrowthDiff => { self.truncate_if_no_lifted_heap_growth_diff(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff(_) => { + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowthDiff => { self.truncate_if_no_lifted_heap_growth_diff(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTruncateIfNoLiftedHeapGrowth(_) => { + &Instruction::CallTruncateIfNoLiftedHeapGrowth => { self.truncate_if_no_lifted_heap_growth(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth(_) => { + &Instruction::ExecuteTruncateIfNoLiftedHeapGrowth => { self.truncate_if_no_lifted_heap_growth(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetAttributedVariableList(_) => { + &Instruction::CallGetAttributedVariableList => { self.get_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetAttributedVariableList(_) => { + &Instruction::ExecuteGetAttributedVariableList => { self.get_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetAttrVarQueueDelimiter(_) => { + &Instruction::CallGetAttrVarQueueDelimiter => { self.get_attr_var_queue_delimiter(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetAttrVarQueueDelimiter(_) => { + &Instruction::ExecuteGetAttrVarQueueDelimiter => { self.get_attr_var_queue_delimiter(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetAttrVarQueueBeyond(_) => { + &Instruction::CallGetAttrVarQueueBeyond => { self.get_attr_var_queue_beyond(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetAttrVarQueueBeyond(_) => { + &Instruction::ExecuteGetAttrVarQueueBeyond => { self.get_attr_var_queue_beyond(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetBValue(_) => { + &Instruction::CallGetBValue => { self.get_b_value(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetBValue(_) => { + &Instruction::ExecuteGetBValue => { self.get_b_value(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetContinuationChunk(_) => { + &Instruction::CallGetContinuationChunk => { self.get_continuation_chunk(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetContinuationChunk(_) => { + &Instruction::ExecuteGetContinuationChunk => { self.get_continuation_chunk(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLookupDBRef(_) => { + &Instruction::CallLookupDBRef => { self.lookup_db_ref(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLookupDBRef(_) => { + &Instruction::ExecuteLookupDBRef => { self.lookup_db_ref(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetNextOpDBRef(_) => { + &Instruction::CallGetNextOpDBRef => { self.get_next_op_db_ref(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetNextOpDBRef(_) => { + &Instruction::ExecuteGetNextOpDBRef => { self.get_next_op_db_ref(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallIsPartialString(_) => { + &Instruction::CallIsPartialString => { self.is_partial_string(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsPartialString(_) => { + &Instruction::ExecuteIsPartialString => { self.is_partial_string(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHalt(_) => { + &Instruction::CallHalt => { self.halt(); self.machine_st.p += 1; } - &Instruction::ExecuteHalt(_) => { + &Instruction::ExecuteHalt => { self.halt(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallGetLiftedHeapFromOffset(_) => { + &Instruction::CallGetLiftedHeapFromOffset => { self.get_lifted_heap_from_offset(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetLiftedHeapFromOffset(_) => { + &Instruction::ExecuteGetLiftedHeapFromOffset => { self.get_lifted_heap_from_offset(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetLiftedHeapFromOffsetDiff(_) => { + &Instruction::CallGetLiftedHeapFromOffsetDiff => { self.get_lifted_heap_from_offset_diff(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetLiftedHeapFromOffsetDiff(_) => { + &Instruction::ExecuteGetLiftedHeapFromOffsetDiff => { self.get_lifted_heap_from_offset_diff(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetSCCCleaner(_) => { + &Instruction::CallGetSCCCleaner => { self.get_scc_cleaner(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetSCCCleaner(_) => { + &Instruction::ExecuteGetSCCCleaner => { self.get_scc_cleaner(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHeadIsDynamic(_) => { + &Instruction::CallHeadIsDynamic => { self.head_is_dynamic(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHeadIsDynamic(_) => { + &Instruction::ExecuteHeadIsDynamic => { self.head_is_dynamic(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInstallSCCCleaner(_) => { + &Instruction::CallInstallSCCCleaner => { self.install_scc_cleaner(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInstallSCCCleaner(_) => { + &Instruction::ExecuteInstallSCCCleaner => { self.install_scc_cleaner(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInstallInferenceCounter(_) => { + &Instruction::CallInstallInferenceCounter => { try_or_throw!(self.machine_st, self.install_inference_counter()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInstallInferenceCounter(_) => { + &Instruction::ExecuteInstallInferenceCounter => { try_or_throw!(self.machine_st, self.install_inference_counter()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLiftedHeapLength(_) => { + &Instruction::CallLiftedHeapLength => { self.lifted_heap_length(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLiftedHeapLength(_) => { + &Instruction::ExecuteLiftedHeapLength => { self.lifted_heap_length(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadLibraryAsStream(_) => { + &Instruction::CallLoadLibraryAsStream => { try_or_throw!(self.machine_st, self.load_library_as_stream()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadLibraryAsStream(_) => { + &Instruction::ExecuteLoadLibraryAsStream => { try_or_throw!(self.machine_st, self.load_library_as_stream()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallModuleExists(_) => { + &Instruction::CallModuleExists => { self.module_exists(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteModuleExists(_) => { + &Instruction::ExecuteModuleExists => { self.module_exists(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNextEP(_) => { + &Instruction::CallNextEP => { self.next_ep(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNextEP(_) => { + &Instruction::ExecuteNextEP => { self.next_ep(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNoSuchPredicate(_) => { + &Instruction::CallNoSuchPredicate => { try_or_throw!(self.machine_st, self.no_such_predicate()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNoSuchPredicate(_) => { + &Instruction::ExecuteNoSuchPredicate => { try_or_throw!(self.machine_st, self.no_such_predicate()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNumberToChars(_) => { + &Instruction::CallNumberToChars => { self.number_to_chars(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNumberToChars(_) => { + &Instruction::ExecuteNumberToChars => { self.number_to_chars(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallNumberToCodes(_) => { + &Instruction::CallNumberToCodes => { self.number_to_codes(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNumberToCodes(_) => { + &Instruction::ExecuteNumberToCodes => { self.number_to_codes(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallOpDeclaration(_) => { + &Instruction::CallOpDeclaration => { try_or_throw!(self.machine_st, self.op_declaration()); self.machine_st.p += 1; } - &Instruction::ExecuteOpDeclaration(_) => { + &Instruction::ExecuteOpDeclaration => { try_or_throw!(self.machine_st, self.op_declaration()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallOpen(_) => { + &Instruction::CallOpen => { try_or_throw!(self.machine_st, self.open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteOpen(_) => { + &Instruction::ExecuteOpen => { try_or_throw!(self.machine_st, self.open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetStreamOptions(_) => { + &Instruction::CallSetStreamOptions => { try_or_throw!(self.machine_st, self.set_stream_options()); self.machine_st.p += 1; } - &Instruction::ExecuteSetStreamOptions(_) => { + &Instruction::ExecuteSetStreamOptions => { try_or_throw!(self.machine_st, self.set_stream_options()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallNextStream(_) => { + &Instruction::CallNextStream => { self.next_stream(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteNextStream(_) => { + &Instruction::ExecuteNextStream => { self.next_stream(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPartialStringTail(_) => { + &Instruction::CallPartialStringTail => { self.partial_string_tail(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePartialStringTail(_) => { + &Instruction::ExecutePartialStringTail => { self.partial_string_tail(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPeekByte(_) => { + &Instruction::CallPeekByte => { try_or_throw!(self.machine_st, self.peek_byte()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePeekByte(_) => { + &Instruction::ExecutePeekByte => { try_or_throw!(self.machine_st, self.peek_byte()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPeekChar(_) => { + &Instruction::CallPeekChar => { try_or_throw!(self.machine_st, self.peek_char()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePeekChar(_) => { + &Instruction::ExecutePeekChar => { try_or_throw!(self.machine_st, self.peek_char()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPeekCode(_) => { + &Instruction::CallPeekCode => { try_or_throw!(self.machine_st, self.peek_code()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePeekCode(_) => { + &Instruction::ExecutePeekCode => { try_or_throw!(self.machine_st, self.peek_code()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPointsToContinuationResetMarker(_) => { + &Instruction::CallPointsToContinuationResetMarker => { self.points_to_continuation_reset_marker(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePointsToContinuationResetMarker(_) => { + &Instruction::ExecutePointsToContinuationResetMarker => { self.points_to_continuation_reset_marker(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPutByte(_) => { + &Instruction::CallPutByte => { try_or_throw!(self.machine_st, self.put_byte()); self.machine_st.p += 1; } - &Instruction::ExecutePutByte(_) => { + &Instruction::ExecutePutByte => { try_or_throw!(self.machine_st, self.put_byte()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPutChar(_) => { + &Instruction::CallPutChar => { try_or_throw!(self.machine_st, self.put_char()); self.machine_st.p += 1; } - &Instruction::ExecutePutChar(_) => { + &Instruction::ExecutePutChar => { try_or_throw!(self.machine_st, self.put_char()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPutChars(_) => { + &Instruction::CallPutChars => { try_or_throw!(self.machine_st, self.put_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePutChars(_) => { + &Instruction::ExecutePutChars => { try_or_throw!(self.machine_st, self.put_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPutCode(_) => { + &Instruction::CallPutCode => { try_or_throw!(self.machine_st, self.put_code()); self.machine_st.p += 1; } - &Instruction::ExecutePutCode(_) => { + &Instruction::ExecutePutCode => { try_or_throw!(self.machine_st, self.put_code()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallReadQueryTerm(_) => { + &Instruction::CallReadQueryTerm => { try_or_throw!(self.machine_st, self.read_query_term()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteReadQueryTerm(_) => { + &Instruction::ExecuteReadQueryTerm => { try_or_throw!(self.machine_st, self.read_query_term()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallReadTerm(_) => { + &Instruction::CallReadTerm => { try_or_throw!(self.machine_st, self.read_term()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteReadTerm(_) => { + &Instruction::ExecuteReadTerm => { try_or_throw!(self.machine_st, self.read_term()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallRedoAttrVarBinding(_) => { + &Instruction::CallRedoAttrVarBinding => { self.redo_attr_var_binding(); self.machine_st.p += 1; } - &Instruction::ExecuteRedoAttrVarBinding(_) => { + &Instruction::ExecuteRedoAttrVarBinding => { self.redo_attr_var_binding(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRemoveCallPolicyCheck(_) => { + &Instruction::CallRemoveCallPolicyCheck => { self.remove_call_policy_check(); self.machine_st.p += 1; } - &Instruction::ExecuteRemoveCallPolicyCheck(_) => { + &Instruction::ExecuteRemoveCallPolicyCheck => { self.remove_call_policy_check(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRemoveInferenceCounter(_) => { + &Instruction::CallRemoveInferenceCounter => { self.remove_inference_counter(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteRemoveInferenceCounter(_) => { + &Instruction::ExecuteRemoveInferenceCounter => { self.remove_inference_counter(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallResetContinuationMarker(_) => { + &Instruction::CallResetContinuationMarker => { self.reset_continuation_marker(); self.machine_st.p += 1; } - &Instruction::ExecuteResetContinuationMarker(_) => { + &Instruction::ExecuteResetContinuationMarker => { self.reset_continuation_marker(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRestoreCutPolicy(_) => { + &Instruction::CallRestoreCutPolicy => { self.restore_cut_policy(); self.machine_st.p += 1; } - &Instruction::ExecuteRestoreCutPolicy(_) => { + &Instruction::ExecuteRestoreCutPolicy => { self.restore_cut_policy(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetCutPoint(r, _) => { + &Instruction::CallSetCutPoint(r) => { if !self.set_cut_point(r) { step_or_fail!(self, self.machine_st.p += 1); } } - &Instruction::ExecuteSetCutPoint(r, _) => { + &Instruction::ExecuteSetCutPoint(r) => { let cp = self.machine_st.cp; if !self.set_cut_point(r) { @@ -4040,994 +4031,994 @@ impl Machine { self.machine_st.cp = cp; } } - &Instruction::CallSetInput(_) => { + &Instruction::CallSetInput => { try_or_throw!(self.machine_st, self.set_input()); self.machine_st.p += 1; } - &Instruction::ExecuteSetInput(_) => { + &Instruction::ExecuteSetInput => { try_or_throw!(self.machine_st, self.set_input()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetOutput(_) => { + &Instruction::CallSetOutput => { try_or_throw!(self.machine_st, self.set_output()); self.machine_st.p += 1; } - &Instruction::ExecuteSetOutput(_) => { + &Instruction::ExecuteSetOutput => { try_or_throw!(self.machine_st, self.set_output()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallStoreBacktrackableGlobalVar(_) => { + &Instruction::CallStoreBacktrackableGlobalVar => { self.store_backtrackable_global_var(); self.machine_st.p += 1; } - &Instruction::ExecuteStoreBacktrackableGlobalVar(_) => { + &Instruction::ExecuteStoreBacktrackableGlobalVar => { self.store_backtrackable_global_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallStoreGlobalVar(_) => { + &Instruction::CallStoreGlobalVar => { self.store_global_var(); self.machine_st.p += 1; } - &Instruction::ExecuteStoreGlobalVar(_) => { + &Instruction::ExecuteStoreGlobalVar => { self.store_global_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallStreamProperty(_) => { + &Instruction::CallStreamProperty => { try_or_throw!(self.machine_st, self.stream_property()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteStreamProperty(_) => { + &Instruction::ExecuteStreamProperty => { try_or_throw!(self.machine_st, self.stream_property()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetStreamPosition(_) => { + &Instruction::CallSetStreamPosition => { try_or_throw!(self.machine_st, self.set_stream_position()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetStreamPosition(_) => { + &Instruction::ExecuteSetStreamPosition => { try_or_throw!(self.machine_st, self.set_stream_position()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInferenceLevel(_) => { + &Instruction::CallInferenceLevel => { self.inference_level(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInferenceLevel(_) => { + &Instruction::ExecuteInferenceLevel => { self.inference_level(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCleanUpBlock(_) => { + &Instruction::CallCleanUpBlock => { self.clean_up_block(); self.machine_st.p += 1; } - &Instruction::ExecuteCleanUpBlock(_) => { + &Instruction::ExecuteCleanUpBlock => { self.clean_up_block(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallFail(_) | &Instruction::ExecuteFail(_) => { + &Instruction::CallFail | &Instruction::ExecuteFail => { self.machine_st.backtrack(); } - &Instruction::CallGetBall(_) => { + &Instruction::CallGetBall => { self.get_ball(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetBall(_) => { + &Instruction::ExecuteGetBall => { self.get_ball(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetCurrentBlock(_) => { + &Instruction::CallGetCurrentBlock => { self.get_current_block(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetCurrentBlock(_) => { + &Instruction::ExecuteGetCurrentBlock => { self.get_current_block(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetCutPoint(_) => { + &Instruction::CallGetCutPoint => { self.get_cut_point(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetCutPoint(_) => { + &Instruction::ExecuteGetCutPoint => { self.get_cut_point(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetDoubleQuotes(_) => { + &Instruction::CallGetDoubleQuotes => { self.get_double_quotes(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetDoubleQuotes(_) => { + &Instruction::ExecuteGetDoubleQuotes => { self.get_double_quotes(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInstallNewBlock(_) => { + &Instruction::CallInstallNewBlock => { self.machine_st.install_new_block(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteInstallNewBlock(_) => { + &Instruction::ExecuteInstallNewBlock => { self.machine_st.install_new_block(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMaybe(_) => { + &Instruction::CallMaybe => { self.maybe(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMaybe(_) => { + &Instruction::ExecuteMaybe => { self.maybe(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCpuNow(_) => { + &Instruction::CallCpuNow => { self.cpu_now(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCpuNow(_) => { + &Instruction::ExecuteCpuNow => { self.cpu_now(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeterministicLengthRundown(_) => { + &Instruction::CallDeterministicLengthRundown => { try_or_throw!(self.machine_st, self.det_length_rundown()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeterministicLengthRundown(_) => { + &Instruction::ExecuteDeterministicLengthRundown => { try_or_throw!(self.machine_st, self.det_length_rundown()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpOpen(_) => { + &Instruction::CallHttpOpen => { try_or_throw!(self.machine_st, self.http_open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpOpen(_) => { + &Instruction::ExecuteHttpOpen => { try_or_throw!(self.machine_st, self.http_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpListen(_) => { + &Instruction::CallHttpListen => { try_or_throw!(self.machine_st, self.http_listen()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpListen(_) => { + &Instruction::ExecuteHttpListen => { try_or_throw!(self.machine_st, self.http_listen()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpAccept(_) => { + &Instruction::CallHttpAccept => { try_or_throw!(self.machine_st, self.http_accept()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpAccept(_) => { + &Instruction::ExecuteHttpAccept => { try_or_throw!(self.machine_st, self.http_accept()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallHttpAnswer(_) => { + &Instruction::CallHttpAnswer => { try_or_throw!(self.machine_st, self.http_answer()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHttpAnswer(_) => { + &Instruction::ExecuteHttpAnswer => { try_or_throw!(self.machine_st, self.http_answer()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadForeignLib(_) => { + &Instruction::CallLoadForeignLib => { try_or_throw!(self.machine_st, self.load_foreign_lib()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadForeignLib(_) => { + &Instruction::ExecuteLoadForeignLib => { try_or_throw!(self.machine_st, self.load_foreign_lib()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallForeignCall(_) => { + &Instruction::CallForeignCall => { try_or_throw!(self.machine_st, self.foreign_call()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteForeignCall(_) => { + &Instruction::ExecuteForeignCall => { try_or_throw!(self.machine_st, self.foreign_call()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDefineForeignStruct(_) => { + &Instruction::CallDefineForeignStruct => { try_or_throw!(self.machine_st, self.define_foreign_struct()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDefineForeignStruct(_) => { + &Instruction::ExecuteDefineForeignStruct => { try_or_throw!(self.machine_st, self.define_foreign_struct()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurrentTime(_) => { + &Instruction::CallCurrentTime => { self.current_time(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurrentTime(_) => { + &Instruction::ExecuteCurrentTime => { self.current_time(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallQuotedToken(_) => { + &Instruction::CallQuotedToken => { self.quoted_token(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteQuotedToken(_) => { + &Instruction::ExecuteQuotedToken => { self.quoted_token(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallReadTermFromChars(_) => { + &Instruction::CallReadTermFromChars => { try_or_throw!(self.machine_st, self.read_term_from_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteReadTermFromChars(_) => { + &Instruction::ExecuteReadTermFromChars => { try_or_throw!(self.machine_st, self.read_term_from_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallResetBlock(_) => { + &Instruction::CallResetBlock => { self.reset_block(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteResetBlock(_) => { + &Instruction::ExecuteResetBlock => { self.reset_block(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallReturnFromVerifyAttr(_) | - &Instruction::ExecuteReturnFromVerifyAttr(_) => { + &Instruction::CallReturnFromVerifyAttr | + &Instruction::ExecuteReturnFromVerifyAttr => { self.return_from_verify_attr(); } - &Instruction::CallSetBall(_) => { + &Instruction::CallSetBall => { self.set_ball(); self.machine_st.p += 1; } - &Instruction::ExecuteSetBall(_) => { + &Instruction::ExecuteSetBall => { self.set_ball(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPushBallStack(_) => { + &Instruction::CallPushBallStack => { self.push_ball_stack(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePushBallStack(_) => { + &Instruction::ExecutePushBallStack => { self.push_ball_stack(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPopBallStack(_) => { + &Instruction::CallPopBallStack => { self.pop_ball_stack(); self.machine_st.p += 1; } - &Instruction::ExecutePopBallStack(_) => { + &Instruction::ExecutePopBallStack => { self.pop_ball_stack(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPopFromBallStack(_) => { + &Instruction::CallPopFromBallStack => { self.pop_from_ball_stack(); self.machine_st.p += 1; } - &Instruction::ExecutePopFromBallStack(_) => { + &Instruction::ExecutePopFromBallStack => { self.pop_from_ball_stack(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetCutPointByDefault(r, _) => { + &Instruction::CallSetCutPointByDefault(r) => { self.set_cut_point_by_default(r); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetCutPointByDefault(r, _) => { + &Instruction::ExecuteSetCutPointByDefault(r) => { self.set_cut_point_by_default(r); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetDoubleQuotes(_) => { + &Instruction::CallSetDoubleQuotes => { self.set_double_quotes(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetDoubleQuotes(_) => { + &Instruction::ExecuteSetDoubleQuotes => { self.set_double_quotes(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetSeed(_) => { + &Instruction::CallSetSeed => { self.set_seed(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSetSeed(_) => { + &Instruction::ExecuteSetSeed => { self.set_seed(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSkipMaxList(_) => { + &Instruction::CallSkipMaxList => { try_or_throw!(self.machine_st, self.machine_st.skip_max_list()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSkipMaxList(_) => { + &Instruction::ExecuteSkipMaxList => { try_or_throw!(self.machine_st, self.machine_st.skip_max_list()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSleep(_) => { + &Instruction::CallSleep => { self.sleep(); self.machine_st.p += 1; } - &Instruction::ExecuteSleep(_) => { + &Instruction::ExecuteSleep => { self.sleep(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSocketClientOpen(_) => { + &Instruction::CallSocketClientOpen => { try_or_throw!(self.machine_st, self.socket_client_open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSocketClientOpen(_) => { + &Instruction::ExecuteSocketClientOpen => { try_or_throw!(self.machine_st, self.socket_client_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSocketServerOpen(_) => { + &Instruction::CallSocketServerOpen => { try_or_throw!(self.machine_st, self.socket_server_open()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSocketServerOpen(_) => { + &Instruction::ExecuteSocketServerOpen => { try_or_throw!(self.machine_st, self.socket_server_open()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSocketServerAccept(_) => { + &Instruction::CallSocketServerAccept => { try_or_throw!(self.machine_st, self.socket_server_accept()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteSocketServerAccept(_) => { + &Instruction::ExecuteSocketServerAccept => { try_or_throw!(self.machine_st, self.socket_server_accept()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSocketServerClose(_) => { + &Instruction::CallSocketServerClose => { try_or_throw!(self.machine_st, self.socket_server_close()); self.machine_st.p += 1; } - &Instruction::ExecuteSocketServerClose(_) => { + &Instruction::ExecuteSocketServerClose => { try_or_throw!(self.machine_st, self.socket_server_close()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallTLSAcceptClient(_) => { + &Instruction::CallTLSAcceptClient => { try_or_throw!(self.machine_st, self.tls_accept_client()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTLSAcceptClient(_) => { + &Instruction::ExecuteTLSAcceptClient => { try_or_throw!(self.machine_st, self.tls_accept_client()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTLSClientConnect(_) => { + &Instruction::CallTLSClientConnect => { try_or_throw!(self.machine_st, self.tls_client_connect()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTLSClientConnect(_) => { + &Instruction::ExecuteTLSClientConnect => { try_or_throw!(self.machine_st, self.tls_client_connect()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSucceed(_) => { + &Instruction::CallSucceed => { self.machine_st.p += 1; } - &Instruction::ExecuteSucceed(_) => { + &Instruction::ExecuteSucceed => { self.machine_st.p = self.machine_st.cp; } - &Instruction::CallTermAttributedVariables(_) => { + &Instruction::CallTermAttributedVariables => { self.term_attributed_variables(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTermAttributedVariables(_) => { + &Instruction::ExecuteTermAttributedVariables => { self.term_attributed_variables(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTermVariables(_) => { + &Instruction::CallTermVariables => { self.term_variables(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTermVariables(_) => { + &Instruction::ExecuteTermVariables => { self.term_variables(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTermVariablesUnderMaxDepth(_) => { + &Instruction::CallTermVariablesUnderMaxDepth => { self.term_variables_under_max_depth(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteTermVariablesUnderMaxDepth(_) => { + &Instruction::ExecuteTermVariablesUnderMaxDepth => { self.term_variables_under_max_depth(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallTruncateLiftedHeapTo(_) => { + &Instruction::CallTruncateLiftedHeapTo => { self.truncate_lifted_heap_to(); self.machine_st.p += 1; } - &Instruction::ExecuteTruncateLiftedHeapTo(_) => { + &Instruction::ExecuteTruncateLiftedHeapTo => { self.truncate_lifted_heap_to(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallUnifyWithOccursCheck(_) => { + &Instruction::CallUnifyWithOccursCheck => { self.unify_with_occurs_check(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteUnifyWithOccursCheck(_) => { + &Instruction::ExecuteUnifyWithOccursCheck => { self.unify_with_occurs_check(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallUnwindEnvironments(_) => { + &Instruction::CallUnwindEnvironments => { if !self.unwind_environments() { self.machine_st.p += 1; } } - &Instruction::ExecuteUnwindEnvironments(_) => { + &Instruction::ExecuteUnwindEnvironments => { if !self.unwind_environments() { self.machine_st.p = self.machine_st.cp; } } - &Instruction::CallUnwindStack(_) | &Instruction::ExecuteUnwindStack(_) => { + &Instruction::CallUnwindStack | &Instruction::ExecuteUnwindStack => { self.machine_st.unwind_stack(); self.machine_st.backtrack(); } - &Instruction::CallWAMInstructions(_) => { + &Instruction::CallWAMInstructions => { try_or_throw!(self.machine_st, self.wam_instructions()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWAMInstructions(_) => { + &Instruction::ExecuteWAMInstructions => { try_or_throw!(self.machine_st, self.wam_instructions()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInlinedInstructions(_) => { + &Instruction::CallInlinedInstructions => { self.inlined_instructions(); self.machine_st.p += 1; } - &Instruction::ExecuteInlinedInstructions(_) => { + &Instruction::ExecuteInlinedInstructions => { self.inlined_instructions(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallWriteTerm(_) => { + &Instruction::CallWriteTerm => { try_or_throw!(self.machine_st, self.write_term()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWriteTerm(_) => { + &Instruction::ExecuteWriteTerm => { try_or_throw!(self.machine_st, self.write_term()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallWriteTermToChars(_) => { + &Instruction::CallWriteTermToChars => { try_or_throw!(self.machine_st, self.write_term_to_chars()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteWriteTermToChars(_) => { + &Instruction::ExecuteWriteTermToChars => { try_or_throw!(self.machine_st, self.write_term_to_chars()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallScryerPrologVersion(_) => { + &Instruction::CallScryerPrologVersion => { self.scryer_prolog_version(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteScryerPrologVersion(_) => { + &Instruction::ExecuteScryerPrologVersion => { self.scryer_prolog_version(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoRandomByte(_) => { + &Instruction::CallCryptoRandomByte => { self.crypto_random_byte(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoRandomByte(_) => { + &Instruction::ExecuteCryptoRandomByte => { self.crypto_random_byte(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataHash(_) => { + &Instruction::CallCryptoDataHash => { self.crypto_data_hash(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataHash(_) => { + &Instruction::ExecuteCryptoDataHash => { self.crypto_data_hash(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataHKDF(_) => { + &Instruction::CallCryptoDataHKDF => { self.crypto_data_hkdf(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataHKDF(_) => { + &Instruction::ExecuteCryptoDataHKDF => { self.crypto_data_hkdf(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoPasswordHash(_) => { + &Instruction::CallCryptoPasswordHash => { self.crypto_password_hash(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoPasswordHash(_) => { + &Instruction::ExecuteCryptoPasswordHash => { self.crypto_password_hash(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataEncrypt(_) => { + &Instruction::CallCryptoDataEncrypt => { self.crypto_data_encrypt(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataEncrypt(_) => { + &Instruction::ExecuteCryptoDataEncrypt => { self.crypto_data_encrypt(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoDataDecrypt(_) => { + &Instruction::CallCryptoDataDecrypt => { self.crypto_data_decrypt(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoDataDecrypt(_) => { + &Instruction::ExecuteCryptoDataDecrypt => { self.crypto_data_decrypt(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCryptoCurveScalarMult(_) => { + &Instruction::CallCryptoCurveScalarMult => { self.crypto_curve_scalar_mult(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCryptoCurveScalarMult(_) => { + &Instruction::ExecuteCryptoCurveScalarMult => { self.crypto_curve_scalar_mult(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519Sign(_) => { + &Instruction::CallEd25519Sign => { self.ed25519_sign(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519Sign(_) => { + &Instruction::ExecuteEd25519Sign => { self.ed25519_sign(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519Verify(_) => { + &Instruction::CallEd25519Verify => { self.ed25519_verify(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519Verify(_) => { + &Instruction::ExecuteEd25519Verify => { self.ed25519_verify(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519NewKeyPair(_) => { + &Instruction::CallEd25519NewKeyPair => { self.ed25519_new_key_pair(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519NewKeyPair(_) => { + &Instruction::ExecuteEd25519NewKeyPair => { self.ed25519_new_key_pair(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallEd25519KeyPairPublicKey(_) => { + &Instruction::CallEd25519KeyPairPublicKey => { self.ed25519_key_pair_public_key(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteEd25519KeyPairPublicKey(_) => { + &Instruction::ExecuteEd25519KeyPairPublicKey => { self.ed25519_key_pair_public_key(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCurve25519ScalarMult(_) => { + &Instruction::CallCurve25519ScalarMult => { self.curve25519_scalar_mult(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCurve25519ScalarMult(_) => { + &Instruction::ExecuteCurve25519ScalarMult => { self.curve25519_scalar_mult(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFirstNonOctet(_) => { + &Instruction::CallFirstNonOctet => { self.first_non_octet(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteFirstNonOctet(_) => { + &Instruction::ExecuteFirstNonOctet => { self.first_non_octet(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadHTML(_) => { + &Instruction::CallLoadHTML => { self.load_html(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadHTML(_) => { + &Instruction::ExecuteLoadHTML => { self.load_html(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadXML(_) => { + &Instruction::CallLoadXML => { self.load_xml(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadXML(_) => { + &Instruction::ExecuteLoadXML => { self.load_xml(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallGetEnv(_) => { + &Instruction::CallGetEnv => { self.get_env(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetEnv(_) => { + &Instruction::ExecuteGetEnv => { self.get_env(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetEnv(_) => { + &Instruction::CallSetEnv => { self.set_env(); self.machine_st.p += 1; } - &Instruction::ExecuteSetEnv(_) => { + &Instruction::ExecuteSetEnv => { self.set_env(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallUnsetEnv(_) => { + &Instruction::CallUnsetEnv => { self.unset_env(); self.machine_st.p += 1; } - &Instruction::ExecuteUnsetEnv(_) => { + &Instruction::ExecuteUnsetEnv => { self.unset_env(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallShell(_) => { + &Instruction::CallShell => { self.shell(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteShell(_) => { + &Instruction::ExecuteShell => { self.shell(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPID(_) => { + &Instruction::CallPID => { self.pid(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePID(_) => { + &Instruction::ExecutePID => { self.pid(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCharsBase64(_) => { + &Instruction::CallCharsBase64 => { try_or_throw!(self.machine_st, self.chars_base64()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCharsBase64(_) => { + &Instruction::ExecuteCharsBase64 => { try_or_throw!(self.machine_st, self.chars_base64()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDevourWhitespace(_) => { + &Instruction::CallDevourWhitespace => { try_or_throw!(self.machine_st, self.devour_whitespace()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDevourWhitespace(_) => { + &Instruction::ExecuteDevourWhitespace => { try_or_throw!(self.machine_st, self.devour_whitespace()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallIsSTOEnabled(_) => { + &Instruction::CallIsSTOEnabled => { self.is_sto_enabled(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsSTOEnabled(_) => { + &Instruction::ExecuteIsSTOEnabled => { self.is_sto_enabled(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallSetSTOAsUnify(_) => { + &Instruction::CallSetSTOAsUnify => { self.set_sto_as_unify(); self.machine_st.p += 1; } - &Instruction::ExecuteSetSTOAsUnify(_) => { + &Instruction::ExecuteSetSTOAsUnify => { self.set_sto_as_unify(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetNSTOAsUnify(_) => { + &Instruction::CallSetNSTOAsUnify => { self.set_nsto_as_unify(); self.machine_st.p += 1; } - &Instruction::ExecuteSetNSTOAsUnify(_) => { + &Instruction::ExecuteSetNSTOAsUnify => { self.set_nsto_as_unify(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallSetSTOWithErrorAsUnify(_) => { + &Instruction::CallSetSTOWithErrorAsUnify => { self.set_sto_with_error_as_unify(); self.machine_st.p += 1; } - &Instruction::ExecuteSetSTOWithErrorAsUnify(_) => { + &Instruction::ExecuteSetSTOWithErrorAsUnify => { self.set_sto_with_error_as_unify(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallHomeDirectory(_) => { + &Instruction::CallHomeDirectory => { self.home_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteHomeDirectory(_) => { + &Instruction::ExecuteHomeDirectory => { self.home_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDebugHook(_) => { + &Instruction::CallDebugHook => { self.debug_hook(); self.machine_st.p += 1; } - &Instruction::ExecuteDebugHook(_) => { + &Instruction::ExecuteDebugHook => { self.debug_hook(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPopCount(_) => { + &Instruction::CallPopCount => { self.pop_count(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePopCount(_) => { + &Instruction::ExecutePopCount => { self.pop_count(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallAddDiscontiguousPredicate(_) => { + &Instruction::CallAddDiscontiguousPredicate => { try_or_throw!(self.machine_st, self.add_discontiguous_predicate()); self.machine_st.p += 1; } - &Instruction::ExecuteAddDiscontiguousPredicate(_) => { + &Instruction::ExecuteAddDiscontiguousPredicate => { try_or_throw!(self.machine_st, self.add_discontiguous_predicate()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddDynamicPredicate(_) => { + &Instruction::CallAddDynamicPredicate => { try_or_throw!(self.machine_st, self.add_dynamic_predicate()); self.machine_st.p += 1; } - &Instruction::ExecuteAddDynamicPredicate(_) => { + &Instruction::ExecuteAddDynamicPredicate => { try_or_throw!(self.machine_st, self.add_dynamic_predicate()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddMultifilePredicate(_) => { + &Instruction::CallAddMultifilePredicate => { try_or_throw!(self.machine_st, self.add_multifile_predicate()); self.machine_st.p += 1; } - &Instruction::ExecuteAddMultifilePredicate(_) => { + &Instruction::ExecuteAddMultifilePredicate => { try_or_throw!(self.machine_st, self.add_multifile_predicate()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddGoalExpansionClause(_) => { + &Instruction::CallAddGoalExpansionClause => { try_or_throw!(self.machine_st, self.add_goal_expansion_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteAddGoalExpansionClause(_) => { + &Instruction::ExecuteAddGoalExpansionClause => { try_or_throw!(self.machine_st, self.add_goal_expansion_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddTermExpansionClause(_) => { + &Instruction::CallAddTermExpansionClause => { try_or_throw!(self.machine_st, self.add_term_expansion_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteAddTermExpansionClause(_) => { + &Instruction::ExecuteAddTermExpansionClause => { try_or_throw!(self.machine_st, self.add_term_expansion_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddInSituFilenameModule(_) => { + &Instruction::CallAddInSituFilenameModule => { try_or_throw!(self.machine_st, self.add_in_situ_filename_module()); self.machine_st.p += 1; } - &Instruction::ExecuteAddInSituFilenameModule(_) => { + &Instruction::ExecuteAddInSituFilenameModule => { try_or_throw!(self.machine_st, self.add_in_situ_filename_module()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallClauseToEvacuable(_) => { + &Instruction::CallClauseToEvacuable => { try_or_throw!(self.machine_st, self.clause_to_evacuable()); self.machine_st.p += 1; } - &Instruction::ExecuteClauseToEvacuable(_) => { + &Instruction::ExecuteClauseToEvacuable => { try_or_throw!(self.machine_st, self.clause_to_evacuable()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallScopedClauseToEvacuable(_) => { + &Instruction::CallScopedClauseToEvacuable => { try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable()); self.machine_st.p += 1; } - &Instruction::ExecuteScopedClauseToEvacuable(_) => { + &Instruction::ExecuteScopedClauseToEvacuable => { try_or_throw!(self.machine_st, self.scoped_clause_to_evacuable()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallConcludeLoad(_) => { + &Instruction::CallConcludeLoad => { try_or_throw!(self.machine_st, self.conclude_load()); self.machine_st.p += 1; } - &Instruction::ExecuteConcludeLoad(_) => { + &Instruction::ExecuteConcludeLoad => { try_or_throw!(self.machine_st, self.conclude_load()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallDeclareModule(_) => { + &Instruction::CallDeclareModule => { try_or_throw!(self.machine_st, self.declare_module()); self.machine_st.p += 1; } - &Instruction::ExecuteDeclareModule(_) => { + &Instruction::ExecuteDeclareModule => { try_or_throw!(self.machine_st, self.declare_module()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallLoadCompiledLibrary(_) => { + &Instruction::CallLoadCompiledLibrary => { try_or_throw!(self.machine_st, self.load_compiled_library()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadCompiledLibrary(_) => { + &Instruction::ExecuteLoadCompiledLibrary => { try_or_throw!(self.machine_st, self.load_compiled_library()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextSource(_) => { + &Instruction::CallLoadContextSource => { self.load_context_source(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextSource(_) => { + &Instruction::ExecuteLoadContextSource => { self.load_context_source(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextFile(_) => { + &Instruction::CallLoadContextFile => { self.load_context_file(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextFile(_) => { + &Instruction::ExecuteLoadContextFile => { self.load_context_file(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextDirectory(_) => { + &Instruction::CallLoadContextDirectory => { self.load_context_directory(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextDirectory(_) => { + &Instruction::ExecuteLoadContextDirectory => { self.load_context_directory(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextModule(_) => { + &Instruction::CallLoadContextModule => { self.load_context_module(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextModule(_) => { + &Instruction::ExecuteLoadContextModule => { self.load_context_module(self.machine_st.registers[1]); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallLoadContextStream(_) => { + &Instruction::CallLoadContextStream => { self.load_context_stream(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteLoadContextStream(_) => { + &Instruction::ExecuteLoadContextStream => { self.load_context_stream(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPopLoadContext(_) => { + &Instruction::CallPopLoadContext => { self.pop_load_context(); self.machine_st.p += 1; } - &Instruction::ExecutePopLoadContext(_) => { + &Instruction::ExecutePopLoadContext => { self.pop_load_context(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPopLoadStatePayload(_) => { + &Instruction::CallPopLoadStatePayload => { self.pop_load_state_payload(); self.machine_st.p += 1; } - &Instruction::ExecutePopLoadStatePayload(_) => { + &Instruction::ExecutePopLoadStatePayload => { self.pop_load_state_payload(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPushLoadContext(_) => { + &Instruction::CallPushLoadContext => { try_or_throw!(self.machine_st, self.push_load_context()); self.machine_st.p += 1; } - &Instruction::ExecutePushLoadContext(_) => { + &Instruction::ExecutePushLoadContext => { try_or_throw!(self.machine_st, self.push_load_context()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPushLoadStatePayload(_) => { + &Instruction::CallPushLoadStatePayload => { self.push_load_state_payload(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePushLoadStatePayload(_) => { + &Instruction::ExecutePushLoadStatePayload => { self.push_load_state_payload(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallUseModule(_) => { + &Instruction::CallUseModule => { try_or_throw!(self.machine_st, self.use_module()); self.machine_st.p += 1; } - &Instruction::ExecuteUseModule(_) => { + &Instruction::ExecuteUseModule => { try_or_throw!(self.machine_st, self.use_module()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallBuiltInProperty(_) => { + &Instruction::CallBuiltInProperty => { self.builtin_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteBuiltInProperty(_) => { + &Instruction::ExecuteBuiltInProperty => { self.builtin_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMetaPredicateProperty(_) => { + &Instruction::CallMetaPredicateProperty => { self.meta_predicate_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMetaPredicateProperty(_) => { + &Instruction::ExecuteMetaPredicateProperty => { self.meta_predicate_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallMultifileProperty(_) => { + &Instruction::CallMultifileProperty => { self.multifile_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteMultifileProperty(_) => { + &Instruction::ExecuteMultifileProperty => { self.multifile_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDiscontiguousProperty(_) => { + &Instruction::CallDiscontiguousProperty => { self.discontiguous_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDiscontiguousProperty(_) => { + &Instruction::ExecuteDiscontiguousProperty => { self.discontiguous_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDynamicProperty(_) => { + &Instruction::CallDynamicProperty => { self.dynamic_property(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDynamicProperty(_) => { + &Instruction::ExecuteDynamicProperty => { self.dynamic_property(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallAbolishClause(_) => { + &Instruction::CallAbolishClause => { try_or_throw!(self.machine_st, self.abolish_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteAbolishClause(_) => { + &Instruction::ExecuteAbolishClause => { try_or_throw!(self.machine_st, self.abolish_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAsserta(_) => { + &Instruction::CallAsserta => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Prepend)); self.machine_st.p += 1; } - &Instruction::ExecuteAsserta(_) => { + &Instruction::ExecuteAsserta => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Prepend)); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAssertz(_) => { + &Instruction::CallAssertz => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Append)); self.machine_st.p += 1; } - &Instruction::ExecuteAssertz(_) => { + &Instruction::ExecuteAssertz => { try_or_throw!(self.machine_st, self.compile_assert(AppendOrPrepend::Append)); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRetract(_) => { + &Instruction::CallRetract => { try_or_throw!(self.machine_st, self.retract_clause()); self.machine_st.p += 1; } - &Instruction::ExecuteRetract(_) => { + &Instruction::ExecuteRetract => { try_or_throw!(self.machine_st, self.retract_clause()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallIsConsistentWithTermQueue(_) => { + &Instruction::CallIsConsistentWithTermQueue => { try_or_throw!(self.machine_st, self.is_consistent_with_term_queue()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsConsistentWithTermQueue(_) => { + &Instruction::ExecuteIsConsistentWithTermQueue => { try_or_throw!(self.machine_st, self.is_consistent_with_term_queue()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::CallFlushTermQueue(_) => { + &Instruction::CallFlushTermQueue => { try_or_throw!(self.machine_st, self.flush_term_queue()); self.machine_st.p += 1; } - &Instruction::ExecuteFlushTermQueue(_) => { + &Instruction::ExecuteFlushTermQueue => { try_or_throw!(self.machine_st, self.flush_term_queue()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallRemoveModuleExports(_) => { + &Instruction::CallRemoveModuleExports => { try_or_throw!(self.machine_st, self.remove_module_exports()); self.machine_st.p += 1; } - &Instruction::ExecuteRemoveModuleExports(_) => { + &Instruction::ExecuteRemoveModuleExports => { try_or_throw!(self.machine_st, self.remove_module_exports()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallAddNonCountedBacktracking(_) => { + &Instruction::CallAddNonCountedBacktracking => { try_or_throw!(self.machine_st, self.add_non_counted_backtracking()); self.machine_st.p += 1; } - &Instruction::ExecuteAddNonCountedBacktracking(_) => { + &Instruction::ExecuteAddNonCountedBacktracking => { try_or_throw!(self.machine_st, self.add_non_counted_backtracking()); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallPredicateDefined(_) => { + &Instruction::CallPredicateDefined => { self.machine_st.fail = !self.predicate_defined(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePredicateDefined(_) => { + &Instruction::ExecutePredicateDefined => { self.machine_st.fail = !self.predicate_defined(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallStripModule(_) => { + &Instruction::CallStripModule => { self.strip_module(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteStripModule(_) => { + &Instruction::ExecuteStripModule => { self.strip_module(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPrepareCallClause(arity, _) => { + &Instruction::CallPrepareCallClause(arity) => { try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePrepareCallClause(arity, _) => { + &Instruction::ExecutePrepareCallClause(arity) => { try_or_throw!(self.machine_st, self.prepare_call_clause(arity)); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallCompileInlineOrExpandedGoal(_) => { + &Instruction::CallCompileInlineOrExpandedGoal => { try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteCompileInlineOrExpandedGoal(_) => { + &Instruction::ExecuteCompileInlineOrExpandedGoal => { try_or_throw!(self.machine_st, self.compile_inline_or_expanded_goal()); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallIsExpandedOrInlined(_) => { + &Instruction::CallIsExpandedOrInlined => { self.machine_st.fail = !self.is_expanded_or_inlined(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteIsExpandedOrInlined(_) => { + &Instruction::ExecuteIsExpandedOrInlined => { self.machine_st.fail = !self.is_expanded_or_inlined(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallFastCallN(arity, _) => { + &Instruction::CallFastCallN(arity) => { let call_at_index = |wam: &mut Machine, name, arity, ptr| { wam.try_call(name, arity, ptr) }; @@ -5043,7 +5034,7 @@ impl Machine { ); } } - &Instruction::ExecuteFastCallN(arity, _) => { + &Instruction::ExecuteFastCallN(arity) => { let call_at_index = |wam: &mut Machine, name, arity, ptr| { wam.try_execute(name, arity, ptr) }; @@ -5059,7 +5050,7 @@ impl Machine { ); } } - &Instruction::CallGetClauseP(_) => { + &Instruction::CallGetClauseP => { let module_name = cell_as_atom!(self.deref_register(3)); let (n, p) = self.get_clause_p(module_name); @@ -5075,7 +5066,7 @@ impl Machine { step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetClauseP(_) => { + &Instruction::ExecuteGetClauseP => { let module_name = cell_as_atom!(self.deref_register(3)); let (n, p) = self.get_clause_p(module_name); @@ -5091,7 +5082,7 @@ impl Machine { step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallInvokeClauseAtP(_) => { + &Instruction::CallInvokeClauseAtP => { let key_cell = self.machine_st.registers[1]; let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap(); @@ -5136,7 +5127,7 @@ impl Machine { self.machine_st.call_at_index(2, p); } - &Instruction::ExecuteInvokeClauseAtP(_) => { + &Instruction::ExecuteInvokeClauseAtP => { let key_cell = self.machine_st.registers[1]; let key = self.machine_st.name_and_arity_from_heap(key_cell).unwrap(); @@ -5181,51 +5172,51 @@ impl Machine { self.machine_st.execute_at_index(2, p); } - &Instruction::CallGetFromAttributedVarList(_) => { + &Instruction::CallGetFromAttributedVarList => { self.get_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetFromAttributedVarList(_) => { + &Instruction::ExecuteGetFromAttributedVarList => { self.get_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallPutToAttributedVarList(_) => { + &Instruction::CallPutToAttributedVarList => { self.put_to_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecutePutToAttributedVarList(_) => { + &Instruction::ExecutePutToAttributedVarList => { self.put_to_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteFromAttributedVarList(_) => { + &Instruction::CallDeleteFromAttributedVarList => { self.delete_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteDeleteFromAttributedVarList(_) => { + &Instruction::ExecuteDeleteFromAttributedVarList => { self.delete_from_attributed_variable_list(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } - &Instruction::CallDeleteAllAttributesFromVar(_) => { + &Instruction::CallDeleteAllAttributesFromVar => { self.delete_all_attributes_from_var(); self.machine_st.p += 1; } - &Instruction::ExecuteDeleteAllAttributesFromVar(_) => { + &Instruction::ExecuteDeleteAllAttributesFromVar => { self.delete_all_attributes_from_var(); self.machine_st.p = self.machine_st.cp; } - &Instruction::CallUnattributedVar(_) => { + &Instruction::CallUnattributedVar => { self.machine_st.unattributed_var(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteUnattributedVar(_) => { + &Instruction::ExecuteUnattributedVar => { self.machine_st.unattributed_var(); - step_or_fail!(self, self.machine_st.p = self.machine_st.cp); + self.machine_st.p = self.machine_st.cp; } - &Instruction::CallGetDBRefs(_) => { + &Instruction::CallGetDBRefs => { self.get_db_refs(); step_or_fail!(self, self.machine_st.p += 1); } - &Instruction::ExecuteGetDBRefs(_) => { + &Instruction::ExecuteGetDBRefs => { self.get_db_refs(); step_or_fail!(self, self.machine_st.p = self.machine_st.cp); } diff --git a/src/machine/load_state.rs b/src/machine/load_state.rs index 802d51eb..56aa88eb 100644 --- a/src/machine/load_state.rs +++ b/src/machine/load_state.rs @@ -441,13 +441,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { term: Term, preprocessor: &mut Preprocessor, ) -> Result { - let tl = preprocessor.try_term_to_tl(self, term, CutContext::BlocksCuts)?; + let tl = preprocessor.try_term_to_tl(self, term)?; Ok(match tl { - TopLevel::Fact(fact) => PredicateClause::Fact(fact), - TopLevel::Rule(rule) => PredicateClause::Rule(rule), - TopLevel::Query(_) => return Err(SessionError::QueryCannotBeDefinedAsFact), - _ => unreachable!(), + TopLevel::Fact(fact, var_data) => PredicateClause::Fact(fact, var_data), + TopLevel::Rule(rule, var_data) => PredicateClause::Rule(rule, var_data), }) } diff --git a/src/machine/loader.rs b/src/machine/loader.rs index f280e5fa..3e9ae50e 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -21,7 +21,6 @@ use std::convert::TryFrom; use std::fmt; use std::mem; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; /* * The loader compiles Prolog terms read from a TermStream instance, @@ -465,6 +464,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { } } + pub(crate) fn read_term_from_heap(&mut self, r: RegType) -> Result { + let machine_st = LS::machine_st(&mut self.payload); + machine_st.read_term_from_heap(r) + } + pub(crate) fn load(mut self) -> Result { while let Some(decl) = self.dequeue_terms()? { self.load_decl(decl)?; @@ -531,106 +535,6 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { Ok(()) } - pub(super) fn read_term_from_heap(&mut self, heap_term_loc: RegType) -> Result { - let machine_st = LS::machine_st(&mut self.payload); - let term_addr = machine_st[heap_term_loc]; - - let mut term_stack = vec![]; - let mut iter = stackful_post_order_iter(&mut machine_st.heap, &mut machine_st.stack, term_addr); - - while let Some(addr) = iter.next() { - let addr = unmark_cell_bits!(addr); - - read_heap_cell!(addr, - (HeapCellValueTag::Lis) => { - use crate::parser::parser::as_partial_string; - - let tail = term_stack.pop().unwrap(); - let head = term_stack.pop().unwrap(); - - match as_partial_string(head, tail) { - Ok((string, Some(tail))) => { - term_stack.push(Term::PartialString(Cell::default(), string, tail)); - } - Ok((string, None)) => { - let atom = machine_st.atom_tbl.build_with(&string); - term_stack.push(Term::CompleteString(Cell::default(), atom)); - } - Err(cons_term) => term_stack.push(cons_term), - } - } - (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, h) => { - let offset_string = format!("_{}", h); - term_stack.push(Term::Var(Cell::default(), Rc::new(offset_string))); - } - (HeapCellValueTag::Cons | HeapCellValueTag::CStr | HeapCellValueTag::Fixnum | - HeapCellValueTag::Char | HeapCellValueTag::F64) => { - term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap())); - } - (HeapCellValueTag::Atom, (name, arity)) => { - let h = iter.focus().value() as usize; - let mut arity = arity; - - if iter.heap.len() > h + arity + 1 { - let value = iter.heap[h + arity + 1]; - - if let Some(idx) = get_structure_index(value) { - // in the second condition, arity == 0, - // meaning idx cannot pertain to this atom - // if it is the direct subterm of a larger - // structure. - if arity > 0 || !iter.direct_subterm_of_str(h) { - term_stack.push( - Term::Literal(Cell::default(), Literal::CodeIndex(idx)) - ); - - arity += 1; - } - } - } - - if arity == 0 { - term_stack.push(Term::Literal(Cell::default(), Literal::Atom(name))); - } else { - let subterms = term_stack - .drain(term_stack.len() - arity ..) - .collect(); - - term_stack.push(Term::Clause(Cell::default(), name, subterms)); - } - } - (HeapCellValueTag::PStr, atom) => { - let tail = term_stack.pop().unwrap(); - - if let Term::Literal(_, Literal::Atom(atom!("[]"))) = &tail { - term_stack.push(Term::CompleteString(Cell::default(), atom)); - } else { - term_stack.push(Term::PartialString( - Cell::default(), - atom.as_str().to_owned(), - Box::new(tail), - )); - } - } - (HeapCellValueTag::PStrLoc, h) => { - let atom = cell_as_atom_cell!(iter.heap[h]).get_name(); - let tail = term_stack.pop().unwrap(); - - term_stack.push(Term::PartialString( - Cell::default(), - atom.as_str().to_owned(), - Box::new(tail), - )); - } - _ => { - } - ); - } - - debug_assert!(term_stack.len() == 1); - Ok(term_stack.pop().unwrap()) - } - fn reset_machine(&mut self) { while let Some(record) = self.payload.retraction_info.records.pop() { match record { @@ -1143,7 +1047,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> { &mut self, r: RegType, ) -> Result, SessionError> { - let export_list = self.read_term_from_heap(r)?; + let machine_st = LS::machine_st(&mut self.payload); + + let export_list = machine_st.read_term_from_heap(r)?; let atom_tbl = &mut LS::machine_st(&mut self.payload).atom_tbl; let export_list = setup_module_export_list(export_list, atom_tbl)?; @@ -1493,6 +1399,106 @@ impl<'a> MachinePreludeView<'a> { } } +impl MachineState { + pub(super) fn read_term_from_heap(&mut self, r: RegType) -> Result { + let term_addr = self[r]; + + let mut term_stack = vec![]; + let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term_addr); + + while let Some(addr) = iter.next() { + let addr = unmark_cell_bits!(addr); + + read_heap_cell!(addr, + (HeapCellValueTag::Lis) => { + use crate::parser::parser::as_partial_string; + + let tail = term_stack.pop().unwrap(); + let head = term_stack.pop().unwrap(); + + match as_partial_string(head, tail) { + Ok((string, Some(tail))) => { + term_stack.push(Term::PartialString(Cell::default(), string, tail)); + } + Ok((string, None)) => { + let atom = self.atom_tbl.build_with(&string); + term_stack.push(Term::CompleteString(Cell::default(), atom)); + } + Err(cons_term) => term_stack.push(cons_term), + } + } + (HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, h) => { + term_stack.push(Term::Var(Cell::default(), VarPtr::from(format!("_{}", h)))); + } + (HeapCellValueTag::Cons | HeapCellValueTag::CStr | HeapCellValueTag::Fixnum | + HeapCellValueTag::Char | HeapCellValueTag::F64) => { + term_stack.push(Term::Literal(Cell::default(), Literal::try_from(addr).unwrap())); + } + (HeapCellValueTag::Atom, (name, arity)) => { + let h = iter.focus().value() as usize; + let mut arity = arity; + + if iter.heap.len() > h + arity + 1 { + let value = iter.heap[h + arity + 1]; + + if let Some(idx) = get_structure_index(value) { + // in the second condition, arity == 0, + // meaning idx cannot pertain to this atom + // if it is the direct subterm of a larger + // structure. + if arity > 0 || !iter.direct_subterm_of_str(h) { + term_stack.push( + Term::Literal(Cell::default(), Literal::CodeIndex(idx)) + ); + + arity += 1; + } + } + } + + if arity == 0 { + term_stack.push(Term::Literal(Cell::default(), Literal::Atom(name))); + } else { + let subterms = term_stack + .drain(term_stack.len() - arity ..) + .collect(); + + term_stack.push(Term::Clause(Cell::default(), name, subterms)); + } + } + (HeapCellValueTag::PStr, atom) => { + let tail = term_stack.pop().unwrap(); + + if let Term::Literal(_, Literal::Atom(atom!("[]"))) = &tail { + term_stack.push(Term::CompleteString(Cell::default(), atom)); + } else { + term_stack.push(Term::PartialString( + Cell::default(), + atom.as_str().to_owned(), + Box::new(tail), + )); + } + } + (HeapCellValueTag::PStrLoc, h) => { + let atom = cell_as_atom_cell!(iter.heap[h]).get_name(); + let tail = term_stack.pop().unwrap(); + + term_stack.push(Term::PartialString( + Cell::default(), + atom.as_str().to_owned(), + Box::new(tail), + )); + } + _ => { + } + ); + } + + debug_assert!(term_stack.len() == 1); + Ok(term_stack.pop().unwrap()) + } +} + impl Machine { pub(crate) fn use_module(&mut self) -> CallResult { let subevacuable_addr = self diff --git a/src/machine/machine_indices.rs b/src/machine/machine_indices.rs index 7c5e761a..ca31e4bd 100644 --- a/src/machine/machine_indices.rs +++ b/src/machine/machine_indices.rs @@ -2,7 +2,6 @@ use crate::parser::ast::*; use crate::arena::*; use crate::atom_table::*; -use crate::fixtures::*; use crate::forms::*; use crate::machine::loader::*; use crate::machine::machine_state::*; @@ -16,7 +15,6 @@ use modular_bitfield::specifiers::*; use std::cmp::Ordering; use std::collections::BTreeSet; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; use crate::types::*; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -228,8 +226,8 @@ impl CodeIndex { } } -pub(crate) type HeapVarDict = IndexMap, HeapCellValue, FxBuildHasher>; -pub(crate) type AllocVarDict = IndexMap, VarData, FxBuildHasher>; +pub(crate) type HeapVarDict = IndexMap; +// pub(crate) type AllocVarDict = IndexMap; pub(crate) type GlobalVarDir = IndexMap), FxBuildHasher>; diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 08c12ccd..de034374 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -21,7 +21,6 @@ use indexmap::IndexMap; use std::convert::TryFrom; use std::fmt; use std::ops::{Index, IndexMut}; -use std::rc::Rc; pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1]; @@ -501,13 +500,13 @@ impl MachineState { pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult { fn push_var_eq_functors<'a>( heap: &mut Heap, - iter: impl Iterator, &'a HeapCellValue)>, + iter: impl Iterator, atom_tbl: &mut AtomTable, ) -> Vec { let mut list_of_var_eqs = vec![]; for (var, binding) in iter { - let var_atom = atom_tbl.build_with(&var); + let var_atom = atom_tbl.build_with(&var.borrow().to_string()); let h = heap.len(); heap.push(atom_as_cell!(atom!("="), 2)); @@ -673,7 +672,7 @@ impl MachineState { let printer = match self.try_from_list(self.registers[6], stub_gen) { Ok(addrs) => { - let mut var_names: IndexMap> = IndexMap::new(); + let mut var_names: IndexMap = IndexMap::new(); for addr in addrs { read_heap_cell!(addr, @@ -691,18 +690,18 @@ impl MachineState { read_heap_cell!(atom, (HeapCellValueTag::Char, c) => { - var_names.insert(var, Rc::new(c.to_string())); + var_names.insert(var, VarPtr::from(c.to_string())); } (HeapCellValueTag::Atom, (name, _arity)) => { debug_assert_eq!(_arity, 0); - var_names.insert(var, Rc::new(name.as_str().to_owned())); + var_names.insert(var, VarPtr::from(name.as_str())); } (HeapCellValueTag::Str, s) => { let (name, arity) = cell_as_atom_cell!(self.heap[s]) .get_name_and_arity(); debug_assert_eq!(arity, 0); - var_names.insert(var, Rc::new(name.as_str().to_owned())); + var_names.insert(var, VarPtr::from(name.as_str())); } _ => { unreachable!(); diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 5193eb66..ddf64d34 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -16,6 +16,7 @@ pub mod machine_state; pub mod machine_state_impl; pub mod mock_wam; pub mod partial_string; +pub mod disjuncts; pub mod preprocessor; pub mod stack; pub mod streams; @@ -67,7 +68,7 @@ pub struct Machine { pub(super) user_error: Stream, pub(super) load_contexts: Vec, pub(super) runtime: Runtime, - pub(super) foreign_function_table: ForeignFunctionTable, + pub(super) foreign_function_table: ForeignFunctionTable, } #[derive(Debug)] @@ -364,46 +365,46 @@ impl Machine { Instruction::BreakFromDispatchLoop, Instruction::InstallVerifyAttr, Instruction::VerifyAttrInterrupt, - Instruction::ExecuteTermGreaterThan(0), - Instruction::ExecuteTermLessThan(0), - Instruction::ExecuteTermGreaterThanOrEqual(0), - Instruction::ExecuteTermLessThanOrEqual(0), - Instruction::ExecuteTermEqual(0), - Instruction::ExecuteTermNotEqual(0), - Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberGreaterThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2)), 0), - Instruction::ExecuteAcyclicTerm(0), - Instruction::ExecuteArg(0), - Instruction::ExecuteCompare(0), - Instruction::ExecuteCopyTerm(0), - Instruction::ExecuteFunctor(0), - Instruction::ExecuteGround(0), - Instruction::ExecuteKeySort(0), - Instruction::ExecuteRead(0), - Instruction::ExecuteSort(0), - Instruction::ExecuteN(1, 0), - Instruction::ExecuteN(2, 0), - Instruction::ExecuteN(3, 0), - Instruction::ExecuteN(4, 0), - Instruction::ExecuteN(5, 0), - Instruction::ExecuteN(6, 0), - Instruction::ExecuteN(7, 0), - Instruction::ExecuteN(8, 0), - Instruction::ExecuteN(9, 0), - Instruction::ExecuteIsAtom(temp_v!(1), 0), - Instruction::ExecuteIsAtomic(temp_v!(1), 0), - Instruction::ExecuteIsCompound(temp_v!(1), 0), - Instruction::ExecuteIsInteger(temp_v!(1), 0), - Instruction::ExecuteIsNumber(temp_v!(1), 0), - Instruction::ExecuteIsRational(temp_v!(1), 0), - Instruction::ExecuteIsFloat(temp_v!(1), 0), - Instruction::ExecuteIsNonVar(temp_v!(1), 0), - Instruction::ExecuteIsVar(temp_v!(1), 0) + Instruction::ExecuteTermGreaterThan, + Instruction::ExecuteTermLessThan, + Instruction::ExecuteTermGreaterThanOrEqual, + Instruction::ExecuteTermLessThanOrEqual, + Instruction::ExecuteTermEqual, + Instruction::ExecuteTermNotEqual, + Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberGreaterThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))), + Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2))), + Instruction::ExecuteAcyclicTerm, + Instruction::ExecuteArg, + Instruction::ExecuteCompare, + Instruction::ExecuteCopyTerm, + Instruction::ExecuteFunctor, + Instruction::ExecuteGround, + Instruction::ExecuteKeySort, + Instruction::ExecuteRead, + Instruction::ExecuteSort, + Instruction::ExecuteN(1), + Instruction::ExecuteN(2), + Instruction::ExecuteN(3), + Instruction::ExecuteN(4), + Instruction::ExecuteN(5), + Instruction::ExecuteN(6), + Instruction::ExecuteN(7), + Instruction::ExecuteN(8), + Instruction::ExecuteN(9), + Instruction::ExecuteIsAtom(temp_v!(1)), + Instruction::ExecuteIsAtomic(temp_v!(1)), + Instruction::ExecuteIsCompound(temp_v!(1)), + Instruction::ExecuteIsInteger(temp_v!(1)), + Instruction::ExecuteIsNumber(temp_v!(1)), + Instruction::ExecuteIsRational(temp_v!(1)), + Instruction::ExecuteIsFloat(temp_v!(1)), + Instruction::ExecuteIsNonVar(temp_v!(1)), + Instruction::ExecuteIsVar(temp_v!(1)) ].into_iter()); for (p, instr) in self.code[impls_offset ..].iter().enumerate() { @@ -689,6 +690,8 @@ impl Machine { fn try_call(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult { let compiled_tl_index = idx.p() as usize; + // println!("calling {}/{}", name.as_str(), arity); + match idx.tag() { IndexPtrTag::DynamicUndefined => { self.machine_st.fail = true; @@ -712,6 +715,8 @@ impl Machine { fn try_execute(&mut self, name: Atom, arity: usize, idx: IndexPtr) -> CallResult { let compiled_tl_index = idx.p() as usize; + // println!("executing {}/{}", name.as_str(), arity); + match idx.tag() { IndexPtrTag::DynamicUndefined => { self.machine_st.fail = true; diff --git a/src/machine/preprocessor.rs b/src/machine/preprocessor.rs index 7f0cc264..a0cab869 100644 --- a/src/machine/preprocessor.rs +++ b/src/machine/preprocessor.rs @@ -2,7 +2,7 @@ use crate::atom_table::*; use crate::codegen::CodeGenSettings; use crate::forms::*; use crate::instructions::*; -use crate::iterators::*; +use crate::machine::disjuncts::*; use crate::machine::loader::*; use crate::machine::machine_errors::*; use crate::parser::ast::*; @@ -10,35 +10,7 @@ use crate::parser::ast::*; use indexmap::IndexSet; use std::cell::Cell; -use std::collections::VecDeque; use std::convert::TryFrom; -use std::rc::Rc; - -/* - * The preprocessor fabricates if-then-else ( .. -> ... ; ...) - * clauses into nameless standalone predicates, which it queues for - * later preprocessing and compilation. Fabricated predicates inherit - * explicit "cut variables" from the handwritten predicate - * surrounding their source if-then-else. They must be specially - * handled. - */ - -#[derive(Clone, Copy, Debug)] -pub(crate) enum CutContext { - BlocksCuts, - HasCutVariable, -} - -pub(crate) fn fold_by_str(terms: I, mut term: Term, sym: Atom) -> Term -where - I: DoubleEndedIterator, -{ - for prec in terms.rev() { - term = Term::Clause(Cell::default(), sym, vec![prec, term]); - } - - term -} pub(crate) fn to_op_decl( prec: u16, @@ -132,6 +104,13 @@ fn setup_module_export( }) } +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 rule = vec![head_term, body_term]; + + Term::Clause(Cell::default(), atom!(":-"), rule) +} + pub(super) fn setup_module_export_list( mut export_list: Term, atom_tbl: &mut AtomTable, @@ -325,110 +304,6 @@ fn setup_meta_predicate<'a, LS: LoadState<'a>>( } } -fn merge_clauses(tls: &mut VecDeque) -> Result { - let mut clauses = vec![]; - - while let Some(tl) = tls.pop_front() { - match tl { - TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => { - return Ok(tl); - } - TopLevel::Query(_) => { - return Err(CompilationError::InconsistentEntry); - } - TopLevel::Fact(fact) => { - let clause = PredicateClause::Fact(fact); - clauses.push(clause); - } - TopLevel::Rule(rule) => { - let clause = PredicateClause::Rule(rule); - clauses.push(clause); - } - TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()), - } - } - - if clauses.is_empty() { - Err(CompilationError::InconsistentEntry) - } else { - Ok(TopLevel::Predicate(clauses)) - } -} - -fn mark_cut_variables_as(terms: &mut Vec, name: Atom) { - for term in terms.iter_mut() { - match term { - &mut Term::Literal(_, Literal::Atom(ref mut var)) if *var == atom!("!") => { - *var = name; - } - _ => {} - } - } -} - -fn mark_cut_variable(term: &mut Term) -> bool { - let cut_var_found = match term { - &mut Term::Literal(_, Literal::Atom(ref var)) if *var == atom!("!") => true, - _ => false, - }; - - if cut_var_found { - *term = Term::Var(Cell::default(), Rc::new(String::from("!"))); - true - } else { - false - } -} - -fn mark_cut_variables(terms: &mut Vec) -> bool { - let mut found_cut_var = false; - - for item in terms.iter_mut() { - found_cut_var = mark_cut_variable(item) || found_cut_var; - } - - found_cut_var -} - -// terms is a list of goals composing one clause in a (;) functor. it -// checks that the first (and only) of these clauses is a ->. if so, -// it expands its terms using a blocked_!. -fn check_for_internal_if_then(terms: &mut Vec) { - if terms.len() != 1 { - return; - } - - if let Some(Term::Clause(_, name, ref subterms)) = terms.last() { - if *name != atom!("->") || source_arity(subterms) != 2 { - return; - } - } else { - return; - } - - if let Some(Term::Clause(_, _, mut subterms)) = terms.pop() { - let mut conq_terms = VecDeque::from(unfold_by_str(subterms.pop().unwrap(), atom!(","))); - let mut pre_cut_terms = VecDeque::from(unfold_by_str(subterms.pop().unwrap(), atom!(","))); - - conq_terms.push_front(Term::Literal( - Cell::default(), - Literal::Atom(atom!("blocked_!")), - )); - - while let Some(term) = pre_cut_terms.pop_back() { - conq_terms.push_front(term); - } - - let tail_term = conq_terms.pop_back().unwrap(); - - terms.push(fold_by_str( - conq_terms.into_iter(), - tail_term, - atom!(","), - )); - } -} - pub(super) fn setup_declaration<'a, LS: LoadState<'a>>( loader: &mut Loader<'a, LS>, mut terms: Vec, @@ -570,7 +445,7 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>( } #[inline] -fn clause_to_query_term<'a, LS: LoadState<'a>>( +pub(super) fn clause_to_query_term<'a, LS: LoadState<'a>>( loader: &mut Loader<'a, LS>, name: Atom, mut terms: Vec, @@ -609,7 +484,7 @@ fn clause_to_query_term<'a, LS: LoadState<'a>>( } #[inline] -fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>( +pub(super) fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>( loader: &mut Loader<'a, LS>, module_name: Atom, name: Atom, @@ -647,308 +522,58 @@ fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>( QueryTerm::Clause(Cell::default(), ct, terms, call_policy) } -fn compute_head(term: &Term) -> Vec { - let mut vars = IndexSet::new(); - - for term in post_order_iter(term) { - if let TermRef::Var(_, _, v) = term { - vars.insert(v.clone()); - } - } - - vars.insert(Rc::new(String::from("!"))); - vars.into_iter() - .map(|v| Term::Var(Cell::default(), v)) - .collect() -} - -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 rule = vec![head_term, body_term]; - - Term::Clause(Cell::default(), atom!(":-"), rule) -} - -// the terms form the body of the rule. We create a head, by -// gathering variables from the body of terms and recording them -// in the head clause. -fn build_rule(body_term: Term) -> (JumpStub, VecDeque) { - // collect the vars of body_term into a head, return the num_vars - // (the arity) as well. - let vars = compute_head(&body_term); - let rule = build_rule_body(&vars, body_term); - - (vars, VecDeque::from(vec![rule])) -} - -fn build_disjunct(body_term: Term) -> (JumpStub, VecDeque) { - let vars = compute_head(&body_term); - let results = unfold_by_str(body_term, atom!(";")) - .into_iter() - .map(|term| { - let mut subterms = unfold_by_str(term, atom!(",")); - mark_cut_variables(&mut subterms); - - check_for_internal_if_then(&mut subterms); - - let term = subterms.pop().unwrap(); - let clause = fold_by_str(subterms.into_iter(), term, atom!(",")); - - build_rule_body(&vars, clause) - }) - .collect(); - - (vars, results) -} - -fn build_if_then(prec: Term, conq: Term) -> (JumpStub, VecDeque) { - let mut prec_seq = unfold_by_str(prec, atom!(",")); - let comma_sym = atom!(","); - let cut_sym = Literal::Atom(atom!("!")); - - prec_seq.push(Term::Literal(Cell::default(), cut_sym)); - - mark_cut_variables_as(&mut prec_seq, atom!("blocked_!")); - - let mut conq_seq = unfold_by_str(conq, atom!(",")); - - mark_cut_variables(&mut conq_seq); - prec_seq.extend(conq_seq.into_iter()); - - let back_term = prec_seq.pop().unwrap(); - let front_term = prec_seq.pop().unwrap(); - - let body_term = Term::Clause( - Cell::default(), - comma_sym, - vec![front_term, back_term], - ); - - build_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym)) -} - #[derive(Debug)] pub(crate) struct Preprocessor { - queue: VecDeque>, settings: CodeGenSettings, } impl Preprocessor { pub(super) fn new(settings: CodeGenSettings) -> Self { Preprocessor { - queue: VecDeque::new(), settings, } } - fn setup_fact(&mut self, term: Term) -> Result { + fn setup_fact(&mut self, term: Term) -> Result<(Fact, VarData), CompilationError> { match term { - Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => Ok(term), + Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => { + let classifier = VariableClassifier::new( + self.settings.default_call_policy(), + ); + + let (head, var_data) = classifier.classify_fact(term)?; + Ok((Fact { head }, var_data)) + } _ => Err(CompilationError::InadmissibleFact), } } - fn to_query_term<'a, LS: LoadState<'a>>( - &mut self, - loader: &mut Loader<'a, LS>, - term: Term, - ) -> Result { - match term { - Term::Literal(_, Literal::Atom(name)) => { - if name == atom!("!") || name == atom!("blocked_!") { - Ok(QueryTerm::BlockedCut) - } else { - Ok(clause_to_query_term( - loader, - name, - vec![], - self.settings.default_call_policy(), - )) - } - } - Term::Literal(_, Literal::Char('!')) => Ok(QueryTerm::BlockedCut), - Term::Var(_, ref v) if v.as_str() == "!" => { - Ok(QueryTerm::UnblockedCut(Cell::default())) - } - Term::Clause(r, name, mut terms) => match (name, source_arity(&terms)) { - (atom!(";"), 2) => { - let term = Term::Clause(r, name, terms); - - let (stub, clauses) = build_disjunct(term); - self.queue.push_back(clauses); - - Ok(QueryTerm::Jump(stub)) - } - (atom!("->"), 2) => { - let conq = terms.pop().unwrap(); - let prec = terms.pop().unwrap(); - - let (stub, clauses) = build_if_then(prec, conq); - self.queue.push_back(clauses); - - Ok(QueryTerm::Jump(stub)) - } - (atom!("\\+"), 1) => { - terms.push(Term::Literal( - Cell::default(), - Literal::Atom(atom!("$fail")), - )); - - let conq = Term::Literal(Cell::default(), Literal::Atom(atom!("true"))); - - let prec = Term::Clause(Cell::default(), atom!("->"), terms); - let terms = vec![prec, conq]; - - let term = Term::Clause(Cell::default(), atom!(";"), terms); - let (stub, clauses) = build_disjunct(term); - - debug_assert!(clauses.len() > 0); - self.queue.push_back(clauses); - - Ok(QueryTerm::Jump(stub)) - } - (atom!("$get_level"), 1) => { - if let Term::Var(_, ref var) = &terms[0] { - Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone())) - } else { - Err(CompilationError::InadmissibleQueryTerm) - } - } - (atom!(":"), 2) => { - let predicate_name = terms.pop().unwrap(); - let module_name = terms.pop().unwrap(); - - match (module_name, predicate_name) { - ( - Term::Literal(_, Literal::Atom(module_name)), - Term::Literal(_, Literal::Atom(predicate_name)), - ) => Ok(qualified_clause_to_query_term( - loader, - module_name, - predicate_name, - vec![], - self.settings.default_call_policy(), - )), - ( - Term::Literal(_, Literal::Atom(module_name)), - Term::Clause(_, name, terms), - ) => Ok(qualified_clause_to_query_term( - loader, - module_name, - name, - terms, - self.settings.default_call_policy() - )), - (module_name, predicate_name) => { - terms.push(module_name); - terms.push(predicate_name); - - Ok(clause_to_query_term( - loader, - atom!("call"), - vec![Term::Clause(r, name, terms)], - self.settings.default_call_policy(), - )) - } - } - } - _ => Ok(clause_to_query_term(loader, name, terms, - self.settings.default_call_policy())), - }, - Term::Var(..) => Ok(QueryTerm::Clause( - Cell::default(), - ClauseType::CallN(1), - vec![term], - self.settings.default_call_policy(), - )), - _ => Err(CompilationError::InadmissibleQueryTerm), - } - } - - fn pre_query_term<'a, LS: LoadState<'a>>( - &mut self, - loader: &mut Loader<'a, LS>, - term: Term, - ) -> Result { - match term { - Term::Clause(r, name, mut subterms) => { - if subterms.len() == 1 && name == atom!("$call_with_inference_counting") { - self.to_query_term(loader, subterms.pop().unwrap()) - .map(|mut query_term| { - query_term.set_call_policy(CallPolicy::Counted); - query_term - }) - } else { - let clause = Term::Clause(r, name, subterms); - self.to_query_term(loader, clause) - } - } - _ => self.to_query_term(loader, term), - } - } - - fn setup_query<'a, LS: LoadState<'a>>( - &mut self, - loader: &mut Loader<'a, LS>, - terms: Vec, - cut_context: CutContext, - ) -> Result, CompilationError> { - let mut query_terms = vec![]; - let mut work_queue = VecDeque::from(terms); - - while let Some(term) = work_queue.pop_front() { - let mut term = term; - - if let Term::Clause(cell, name, terms) = term { - if name == atom!(",") && source_arity(&terms) == 2 { - let term = Term::Clause(cell, name, terms); - let mut subterms = unfold_by_str(term, atom!(",")); - - while let Some(subterm) = subterms.pop() { - work_queue.push_front(subterm); - } - - continue; - } else { - term = Term::Clause(cell, name, terms); - } - } - - if let CutContext::HasCutVariable = cut_context { - mark_cut_variable(&mut term); - } - - query_terms.push(self.pre_query_term(loader, term)?); - } - - Ok(query_terms) - } - fn setup_rule<'a, LS: LoadState<'a>>( &mut self, loader: &mut Loader<'a, LS>, - mut terms: Vec, - cut_context: CutContext, - ) -> Result { - let post_head_terms: Vec<_> = terms.drain(1..).collect(); - let mut query_terms = self.setup_query(loader, post_head_terms, cut_context)?; + head: Term, + body: Term, + ) -> Result<(Rule, VarData), CompilationError> { + let classifier = VariableClassifier::new( + self.settings.default_call_policy(), + ); - let clauses = query_terms.drain(1..).collect(); - let qt = query_terms.pop().unwrap(); + let (head, clauses, var_data) = classifier.classify_rule(loader, head, body)?; - match terms.pop().unwrap() { - Term::Clause(_, name, terms) => Ok(Rule { - head: (name, terms, qt), + match head { + Term::Clause(_, name, terms) => Ok((Rule { + head: (name, terms), clauses, - }), - Term::Literal(_, Literal::Atom(name)) => Ok(Rule { - head: (name, vec![], qt), + }, var_data)), + Term::Literal(_, Literal::Atom(name)) => Ok((Rule { + head: (name, vec![]), clauses, - }), + }, var_data)), _ => Err(CompilationError::InvalidRuleHead), } } + /* fn try_term_to_query<'a, LS: LoadState<'a>>( &mut self, loader: &mut Loader<'a, LS>, @@ -961,63 +586,49 @@ impl Preprocessor { cut_context, )?)) } + */ pub(super) fn try_term_to_tl<'a, LS: LoadState<'a>>( &mut self, loader: &mut Loader<'a, LS>, term: Term, - cut_context: CutContext, ) -> Result { match term { - Term::Clause(r, name, terms) => { - if name == atom!("?-") { - self.try_term_to_query(loader, terms, cut_context) - } else if name == atom!(":-") && terms.len() == 2 { - Ok(TopLevel::Rule(self.setup_rule( - loader, - terms, - cut_context, - )?)) + Term::Clause(r, name, mut terms) => { + let is_rule = name == atom!(":-") && terms.len() == 2; + + if is_rule { + let tail = terms.pop().unwrap(); + let head = terms.pop().unwrap(); + + let (rule, var_data) = self.setup_rule(loader, head, tail)?; + Ok(TopLevel::Rule(rule, var_data)) } else { let term = Term::Clause(r, name, terms); - Ok(TopLevel::Fact(self.setup_fact(term)?)) + let (fact, var_data) = self.setup_fact(term)?; + Ok(TopLevel::Fact(fact, var_data)) } } - term => Ok(TopLevel::Fact(self.setup_fact(term)?)), + term => { + let (fact, var_data) = self.setup_fact(term)?; + Ok(TopLevel::Fact(fact, var_data)) + } } } + /* fn try_terms_to_tls<'a, I: IntoIterator, LS: LoadState<'a>>( &mut self, loader: &mut Loader<'a, LS>, terms: I, - cut_context: CutContext, ) -> Result, CompilationError> { let mut results = VecDeque::new(); for term in terms.into_iter() { - results.push_back(self.try_term_to_tl(loader, term, cut_context)?); + results.push_back(self.try_term_to_tl(loader, term)?); } Ok(results) } - - pub(super) fn parse_queue<'a, LS: LoadState<'a>>( - &mut self, - loader: &mut Loader<'a, LS>, - ) -> Result, CompilationError> { - let mut queue = VecDeque::new(); - - while let Some(terms) = self.queue.pop_front() { - let clauses = merge_clauses(&mut self.try_terms_to_tls( - loader, - terms, - CutContext::HasCutVariable, - )?)?; - - queue.push_back(clauses); - } - - Ok(queue) - } + */ } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 4da3c2f8..94f166f2 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -51,7 +51,6 @@ use std::net::{TcpListener, TcpStream, SocketAddr, ToSocketAddrs}; use std::num::NonZeroU32; use std::ops::Sub; use std::process; -use std::rc::Rc; use std::str::FromStr; use std::sync::Arc; @@ -1445,7 +1444,7 @@ impl Machine { let vars: Vec<_> = vars .union(&result.supp_vars) // difference + union does not cancel. - .map(|v| Term::Var(Cell::default(), Rc::new(format!("_{}", v.get_value())))) + .map(|v| Term::Var(Cell::default(), VarPtr::from(format!("_{}", v.get_value())))) .collect(); let helper_clause_loc = self.code.len(); @@ -1655,8 +1654,8 @@ impl Machine { #[inline(always)] pub(crate) fn is_reset_cont_marker(&self, p: usize) -> bool { match &self.code[p] { - &Instruction::CallResetContinuationMarker(_) | - &Instruction::ExecuteResetContinuationMarker(_) => true, + &Instruction::CallResetContinuationMarker | + &Instruction::ExecuteResetContinuationMarker => true, _ => false } } @@ -4941,9 +4940,7 @@ impl Machine { let p_functor = self.deref_register(2); - let p = to_local_code_ptr(&self.machine_st.heap, p_functor).unwrap(); - - let num_cells = *self.code[p].perm_vars_mut().unwrap(); + let num_cells = self.machine_st.stack.index_and_frame(e).prelude.num_cells; let mut addrs = vec![]; for idx in 1..num_cells + 1 { diff --git a/src/macros.rs b/src/macros.rs index 78c0d89c..c0c929c8 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -540,23 +540,7 @@ macro_rules! functor_term { macro_rules! compare_number_instr { ($cmp: expr, $at_1: expr, $at_2: expr) => {{ $cmp.set_terms($at_1, $at_2); - call_clause!(ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp)), 0) - }}; -} - -macro_rules! call_clause { - ($clause_type:expr, $pvs:expr) => {{ - let mut instr = $clause_type.to_instr(); - instr.perm_vars_mut().map(|pvs| *pvs = $pvs); - instr - }}; -} - -macro_rules! call_clause_by_default { - ($clause_type:expr, $pvs:expr) => {{ - let mut instr = $clause_type.to_instr().to_default(); - instr.perm_vars_mut().map(|pvs| *pvs = $pvs); - instr + ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp)).to_instr() }}; } diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 0933b11c..283a9dc0 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -4,11 +4,11 @@ use crate::machine::machine_indices::*; use crate::parser::char_reader::*; use crate::types::HeapCellValueTag; -use std::cell::Cell; +use std::cell::{Cell, Ref, RefCell, RefMut}; use std::fmt; -use std::hash::Hash; +use std::hash::{Hash, Hasher}; use std::io::{Error as IOError}; -use std::ops::Neg; +use std::ops::{Deref, Neg}; use std::rc::Rc; use std::vec::Vec; @@ -227,7 +227,7 @@ macro_rules! perm_v { }; } -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum GenContext { Head, Mid(usize), @@ -572,6 +572,110 @@ impl Literal { } } + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VarPtr(Rc>); + +impl Hash for VarPtr { + #[inline(always)] + fn hash(&self, hasher: &mut H) { + self.borrow().hash(hasher) + } +} + +impl Deref for VarPtr { + type Target = RefCell; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + self.0.deref() + } +} + +impl VarPtr { + #[inline(always)] + pub(crate) fn borrow(&self) -> Ref<'_, Var> { + self.0.borrow() + } + + #[inline(always)] + pub(crate) fn borrow_mut(&self) -> RefMut<'_, Var> { + self.0.borrow_mut() + } + + pub(crate) fn to_var_num(&self) -> Option { + match *self.borrow() { + Var::Generated(var_num) => Some(var_num), + _ => None, + } + } + + pub(crate) fn set(&self, var: Var) { + let mut var_ref = self.borrow_mut(); + *var_ref = var; + } +} + +impl From for VarPtr { + #[inline(always)] + fn from(value: Var) -> VarPtr { + VarPtr(Rc::new(RefCell::new(value))) + } +} + +impl From for VarPtr { + #[inline(always)] + fn from(value: String) -> VarPtr { + VarPtr::from(Var::from(value)) + } +} + +impl From<&str> for VarPtr { + #[inline(always)] + fn from(value: &str) -> VarPtr { + VarPtr::from(value.to_owned()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Var { + Generated(usize), + InSitu(usize), + Named(String), +} + +impl From for Var { + #[inline(always)] + fn from(value: String) -> Var { + Var::Named(value) + } +} + +impl From<&str> for Var { + #[inline(always)] + fn from(value: &str) -> Var { + Var::Named(value.to_owned()) + } +} + +impl Var { + #[inline(always)] + pub fn as_str(&self) -> Option<&str> { + match self { + Var::Named(value) => Some(&value), + _ => None, + } + } + + #[inline(always)] + pub fn to_string(&self) -> String { + match self { + Var::InSitu(n) | Var::Generated(n) => format!("_{}", n), + Var::Named(value) => value.to_owned(), + } + } +} + #[derive(Debug, Clone)] pub enum Term { AnonVar, @@ -582,7 +686,7 @@ pub enum Term { // other PartialString variants in as_partial_string. PartialString(Cell, String, Box), CompleteString(Cell, Atom), - Var(Cell, Rc), + Var(Cell, VarPtr), } impl Term { @@ -667,3 +771,30 @@ pub fn unfold_by_str(mut term: Term, s: Atom) -> Vec { terms.push(term); terms } + +fn unfold_by_str_ref_once(term: &Term, s: Atom) -> Option<(&Term, &Term)> { + if let Term::Clause(_, ref name, ref subterms) = term { + if name == &s && subterms.len() == 2 { + let fst = &subterms[0]; + let snd = &subterms[1]; + + return Some((fst, snd)); + } + } + + None +} + +pub fn unfold_by_str_ref(mut term: &Term, s: Atom) -> Vec<&Term> { + let mut terms = vec![]; + + while let Some((fst, snd)) = unfold_by_str_ref_once(&term, s) { + terms.push(fst); + term = snd; + } + + terms.push(term); + terms +} + + diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 74f1b930..021147ea 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -8,7 +8,6 @@ use crate::parser::rug::ops::NegAssign; use std::cell::Cell; use std::mem; -use std::rc::Rc; #[derive(Debug, Clone, Copy, PartialEq)] enum TokenType { @@ -427,7 +426,7 @@ impl<'a, R: CharRead> Parser<'a, R> { if v.trim() == "_" { self.terms.push(Term::AnonVar); } else { - self.terms.push(Term::Var(Cell::default(), Rc::new(v))); + self.terms.push(Term::Var(Cell::default(), VarPtr::from(v))); } TokenType::Term diff --git a/src/read.rs b/src/read.rs index c8743c2f..8f70eeec 100644 --- a/src/read.rs +++ b/src/read.rs @@ -317,7 +317,7 @@ impl<'a, 'b> TermWriter<'a, 'b> { fn write_term_to_heap(mut self, term: &'a Term) -> Result { let heap_loc = self.heap.len(); - for term in breadth_first_iter(term, true) { + for term in breadth_first_iter(term, RootIterationPolicy::Iterated) { let h = self.heap.len(); match &term { @@ -372,9 +372,9 @@ impl<'a, 'b> TermWriter<'a, 'b> { let addr = self.term_as_addr(&term, h); self.heap.push(addr); } - &TermRef::Var(Level::Root, _, ref var) => { + &TermRef::Var(Level::Root, _, ref var_ptr) => { let addr = self.term_as_addr(&term, h); - self.var_dict.insert(var.clone(), heap_loc_as_cell!(h)); + self.var_dict.insert(var_ptr.clone(), heap_loc_as_cell!(h)); self.heap.push(addr); } &TermRef::AnonVar(_) => { diff --git a/src/targets.rs b/src/targets.rs index cbb469f9..56a4c127 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -29,11 +29,13 @@ pub(crate) trait CompilationTarget<'a> { fn argument_to_variable(r: RegType, r: usize) -> Instruction; fn argument_to_value(r: RegType, val: usize) -> Instruction; + fn unsafe_argument_to_value(r: RegType, val: usize) -> Instruction; fn move_to_register(r: RegType, val: usize) -> Instruction; fn subterm_to_variable(r: RegType) -> Instruction; fn subterm_to_value(r: RegType) -> Instruction; + fn unsafe_subterm_to_value(r: RegType) -> Instruction; fn clause_arg_to_instr(r: RegType) -> Instruction; } @@ -42,7 +44,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction { type Iterator = FactIterator<'a>; fn iter(term: &'a Term) -> Self::Iterator { - breadth_first_iter(term, false) // do not iterate over the root clause if one exists. + breadth_first_iter(term, RootIterationPolicy::NotIterated) } fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Instruction { @@ -95,6 +97,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction { Instruction::GetValue(arg, val) } + fn unsafe_argument_to_value(arg: RegType, val: usize) -> Instruction { + Instruction::GetValue(arg, val) + } + fn subterm_to_variable(val: RegType) -> Instruction { Instruction::UnifyVariable(val) } @@ -103,6 +109,10 @@ impl<'a> CompilationTarget<'a> for FactInstruction { Instruction::UnifyValue(val) } + fn unsafe_subterm_to_value(val: RegType) -> Instruction { + Instruction::UnifyLocalValue(val) + } + fn clause_arg_to_instr(val: RegType) -> Instruction { Instruction::UnifyVariable(val) } @@ -165,6 +175,13 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { Instruction::PutValue(arg, val) } + fn unsafe_argument_to_value(arg: RegType, val: usize) -> Instruction { + match arg { + RegType::Perm(p) => Instruction::PutUnsafeValue(p, val), + RegType::Temp(_) => Instruction::PutValue(arg, val), + } + } + fn subterm_to_variable(val: RegType) -> Instruction { Instruction::SetVariable(val) } @@ -173,6 +190,10 @@ impl<'a> CompilationTarget<'a> for QueryInstruction { Instruction::SetValue(val) } + fn unsafe_subterm_to_value(val: RegType) -> Instruction { + Instruction::SetLocalValue(val) + } + fn clause_arg_to_instr(val: RegType) -> Instruction { Instruction::SetValue(val) } diff --git a/src/variable_records.rs b/src/variable_records.rs new file mode 100644 index 00000000..f301d909 --- /dev/null +++ b/src/variable_records.rs @@ -0,0 +1,248 @@ +use crate::parser::ast::*; + +use bit_set::*; +use fxhash::FxBuildHasher; +use indexmap::{IndexMap, IndexSet}; +use std::ops::{Deref, DerefMut}; + +#[derive(Debug, Clone)] +pub struct TempVarData { + pub(crate) use_set: IndexSet<(GenContext, usize), FxBuildHasher>, + pub(crate) no_use_set: BitSet, + pub(crate) conflict_set: BitSet, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BranchDesignator(pub (usize, usize)); + +impl BranchDesignator { + #[inline] + pub fn is_subbranch(&self) -> bool { + (self.0).0 > 0 + } + + #[inline] + pub fn subsumes(&self, branch_designator: &Self) -> bool { + (self.0).0 < (branch_designator.0).0 || self == branch_designator + } +} + +#[derive(Debug, Clone, Copy)] +pub enum VarSafetyStatus { + Needed, + // which branch planted the last unsafe guarded instruction? It may still be needed. + LocallyUnneeded(BranchDesignator), + GloballyUnneeded, +} + +impl VarSafetyStatus { + pub(crate) fn unneeded(current_branch: BranchDesignator) -> Self { + if current_branch.is_subbranch() { + VarSafetyStatus::LocallyUnneeded(current_branch) + } else { + VarSafetyStatus::GloballyUnneeded + } + } + + #[inline] + pub(crate) fn is_unneeded(&self, current_branch: BranchDesignator) -> bool { + match self { + &VarSafetyStatus::Needed => false, + &VarSafetyStatus::LocallyUnneeded(planter_branch) => planter_branch.subsumes(¤t_branch), + &VarSafetyStatus::GloballyUnneeded => true, + } + } + + #[inline] + pub(crate) fn needed_if(needed: bool, branch_designator: BranchDesignator) -> Self { + if needed { + VarSafetyStatus::Needed + } else if (branch_designator.0).0 == 0 { + VarSafetyStatus::GloballyUnneeded + } else { + VarSafetyStatus::LocallyUnneeded(branch_designator) + } + } +} + +#[derive(Debug, Clone, Copy)] +pub enum PermVarAllocation { + Done { shallow_safety: VarSafetyStatus, + deep_safety: VarSafetyStatus }, + Pending, +} + +impl PermVarAllocation { + #[inline] + pub(crate) fn done() -> Self { + PermVarAllocation::Done { + shallow_safety: VarSafetyStatus::Needed, + deep_safety: VarSafetyStatus::Needed, + } + } + + #[inline] + pub(crate) fn pending(&self) -> bool { + match self { + &PermVarAllocation::Pending => true, + _ => false, + } + } +} + +#[derive(Debug, Clone)] +pub enum VarAlloc { + Temp { term_loc: GenContext, + temp_reg: usize, + temp_var_data: TempVarData, + safety: VarSafetyStatus, + to_perm_var_num: Option }, + Perm(usize, PermVarAllocation), // stack offset, allocation info +} + +impl VarAlloc { + #[inline] + pub(crate) fn as_reg_type(&self) -> RegType { + match self { + &VarAlloc::Temp { temp_reg, .. } => RegType::Temp(temp_reg), + &VarAlloc::Perm(r, _) => RegType::Perm(r), + } + } + + #[inline] + pub(crate) fn set_register(&mut self, reg_num: usize) { + match self { + VarAlloc::Perm(ref mut p, _) => *p = reg_num, + VarAlloc::Temp { ref mut temp_reg, .. } => *temp_reg = reg_num, + }; + } +} + +impl TempVarData { + pub(crate) fn new() -> Self { + TempVarData { + use_set: IndexSet::with_hasher(FxBuildHasher::default()), + no_use_set: BitSet::default(), + conflict_set: BitSet::default(), + } + } + + pub(crate) fn uses_reg(&self, reg: usize) -> bool { + for &(_, nreg) in self.use_set.iter() { + if reg == nreg { + return true; + } + } + + return false; + } + + pub(crate) fn populate_conflict_set(&mut self) { + let arity = self.use_set.len(); + let mut conflict_set: BitSet = (1..arity).collect(); + + for &(_, idx) in &self.use_set { + conflict_set.remove(idx); + } + + self.conflict_set = conflict_set; + } +} + +#[derive(Debug, Clone)] +pub struct VariableRecord { + pub allocation: VarAlloc, + pub num_occurrences: usize, + pub running_count: usize, +} + +impl Default for VariableRecord { + fn default() -> Self { + VariableRecord { + allocation: VarAlloc::Perm(0, PermVarAllocation::Pending), + num_occurrences: 0, + running_count: 0, + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct VariableRecords(Vec); + +impl Deref for VariableRecords { + type Target = Vec; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for VariableRecords { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl VariableRecords { + #[inline] + pub(crate) fn new(num_records: usize) -> Self { + Self(vec![VariableRecord::default(); num_records]) + } + + // computes no_use and conflict sets for all temp vars. + pub(crate) fn populate_restricting_sets(&mut self) { + // three stages: + // 1. move the use sets of each variable to a local IndexMap, use_set + // (iterate mutably, swap mutable refs). + // 2. drain use_set. For each use set of U, add into the + // no-use sets of appropriate variables T =/= U. + // 3. Move the use sets back to their original locations in the fixture. + // Compute the conflict set of u. + + // 1. + let mut use_sets: IndexMap> = IndexMap::new(); + + for (var_gen_index, record) in self.0.iter_mut().enumerate() { + match &mut record.allocation { + VarAlloc::Temp { temp_var_data, .. } => { + let use_set = std::mem::replace( + &mut temp_var_data.use_set, + IndexSet::with_hasher(FxBuildHasher::default()), + ); + + use_sets.insert(var_gen_index, use_set); + } + _ => { + } + } + } + + for (u, use_set) in use_sets.drain(..) { + // 2. + for &(term_loc, reg) in &use_set { + if let GenContext::Last(cn_u) = term_loc { + for (var_gen_index, record) in self.0.iter_mut().enumerate() { + match &mut record.allocation { + VarAlloc::Temp { term_loc, temp_var_data, .. } => { + if cn_u == term_loc.chunk_num() && u != var_gen_index { + if !temp_var_data.uses_reg(reg) { + temp_var_data.no_use_set.insert(reg); + } + } + } + _ => {} + } + } + } + } + + // 3. + if let VarAlloc::Temp{ temp_var_data, .. } = &mut self[u].allocation { + temp_var_data.use_set = use_set; + temp_var_data.populate_conflict_set(); + } + } + } +}