Fixing some showstoppers
- inertness now tracked separately from gas - atomic_impl now correctly rolls over when the argument is inert - syntax fixes - tree shaking
This commit is contained in:
184
Cargo.lock
generated
184
Cargo.lock
generated
@@ -79,12 +79,6 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.21.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -103,12 +97,6 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg_aliases"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chumsky"
|
name = "chumsky"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
@@ -152,7 +140,7 @@ dependencies = [
|
|||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.13",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -167,16 +155,6 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dashmap"
|
|
||||||
version = "4.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"num_cpus",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dyn-clone"
|
name = "dyn-clone"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
@@ -221,15 +199,6 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
|
||||||
dependencies = [
|
|
||||||
"ahash 0.7.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@@ -254,37 +223,19 @@ version = "0.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.2.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "instant"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-lifetimes"
|
name = "io-lifetimes"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
|
checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.3.1",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
@@ -295,7 +246,7 @@ version = "0.4.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.3.1",
|
"hermit-abi",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@@ -310,16 +261,6 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lasso"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aeb7b21a526375c5ca55f1a6dfd4e1fad9fa4edd750f530252a718a44b2608f0"
|
|
||||||
dependencies = [
|
|
||||||
"dashmap",
|
|
||||||
"hashbrown 0.11.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.142"
|
version = "0.2.142"
|
||||||
@@ -332,28 +273,6 @@ version = "0.3.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
|
checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lock_api"
|
|
||||||
version = "0.4.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mappable-rc"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "204651f31b0a6a7b2128d2b92c372cd94607b210c3a6b6e542c57a8cfd4db996"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
@@ -363,16 +282,6 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num_cpus"
|
|
||||||
version = "1.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi 0.2.6",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.17.1"
|
version = "1.17.1"
|
||||||
@@ -381,19 +290,15 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orchid"
|
name = "orchid"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
|
||||||
"chumsky",
|
"chumsky",
|
||||||
"clap",
|
"clap",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.13.2",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lasso",
|
|
||||||
"mappable-rc",
|
|
||||||
"ordered-float",
|
"ordered-float",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"static_init",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -406,31 +311,6 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
|
||||||
dependencies = [
|
|
||||||
"instant",
|
|
||||||
"lock_api",
|
|
||||||
"parking_lot_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot_core"
|
|
||||||
version = "0.8.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"instant",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall",
|
|
||||||
"smallvec",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.56"
|
version = "1.0.56"
|
||||||
@@ -458,15 +338,6 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.2.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.37.19"
|
version = "0.37.19"
|
||||||
@@ -481,12 +352,6 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
@@ -506,51 +371,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "static_init"
|
|
||||||
version = "1.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8a2a1c578e98c1c16fc3b8ec1328f7659a500737d7a0c6d625e73e830ff9c1f6"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cfg_aliases",
|
|
||||||
"libc",
|
|
||||||
"parking_lot",
|
|
||||||
"parking_lot_core",
|
|
||||||
"static_init_macro",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "static_init_macro"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf"
|
|
||||||
dependencies = [
|
|
||||||
"cfg_aliases",
|
|
||||||
"memchr",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.109"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.13"
|
version = "2.0.13"
|
||||||
@@ -579,7 +405,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.13",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "orchid"
|
name = "orchid"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
"Lawrence Bethlenfalvy <lbfalvy@protonmail.com>"
|
"Lawrence Bethlenfalvy <lbfalvy@protonmail.com>"
|
||||||
@@ -12,12 +12,8 @@ authors = [
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
chumsky = "0.9.2"
|
chumsky = "0.9.2"
|
||||||
hashbrown = "0.13.2"
|
hashbrown = "0.13.2"
|
||||||
mappable-rc = "0.1"
|
|
||||||
ordered-float = "3.0"
|
ordered-float = "3.0"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
smallvec = { version = "1.10.0", features = ['const_generics'] }
|
smallvec = { version = "1.10.0", features = ['const_generics'] }
|
||||||
dyn-clone = "1.0.11"
|
dyn-clone = "1.0.11"
|
||||||
lasso = { version = "0.6.0", features = ['multi-threaded'] }
|
clap = { version = "4.2.4", features = ["derive"] }
|
||||||
base64 = "0.21.0"
|
|
||||||
static_init = "1.0.3"
|
|
||||||
clap = { version = "4.2.7", features = ["derive"] }
|
|
||||||
|
|||||||
2
src/external/bool/equals.rs
vendored
2
src/external/bool/equals.rs
vendored
@@ -13,7 +13,7 @@ use super::boolean::Boolean;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Equals2;
|
pub struct Equals2;
|
||||||
externfn_impl!(Equals2, |_: &Self, x: ExprInst| {Ok(Equals1{x})});
|
externfn_impl!(Equals2, |_: &Self, x: ExprInst| Ok(Equals1{x}));
|
||||||
|
|
||||||
/// Partially applied Equals function
|
/// Partially applied Equals function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/bool/ifthenelse.rs
vendored
2
src/external/bool/ifthenelse.rs
vendored
@@ -13,7 +13,7 @@ use super::Boolean;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct IfThenElse1;
|
pub struct IfThenElse1;
|
||||||
externfn_impl!(IfThenElse1, |_: &Self, x: ExprInst| {Ok(IfThenElse0{x})});
|
externfn_impl!(IfThenElse1, |_: &Self, x: ExprInst| Ok(IfThenElse0{x}));
|
||||||
|
|
||||||
/// Partially applied IfThenElse function
|
/// Partially applied IfThenElse function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/conv/parse_float.rs
vendored
2
src/external/conv/parse_float.rs
vendored
@@ -15,7 +15,7 @@ use crate::{atomic_impl, atomic_redirect, externfn_impl};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ParseFloat1;
|
pub struct ParseFloat1;
|
||||||
externfn_impl!(ParseFloat1, |_: &Self, x: ExprInst| {Ok(ParseFloat0{x})});
|
externfn_impl!(ParseFloat1, |_: &Self, x: ExprInst| Ok(ParseFloat0{x}));
|
||||||
|
|
||||||
/// Applied to_string function
|
/// Applied to_string function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/conv/parse_uint.rs
vendored
2
src/external/conv/parse_uint.rs
vendored
@@ -14,7 +14,7 @@ use crate::parse::int_parser;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ParseUint1;
|
pub struct ParseUint1;
|
||||||
externfn_impl!(ParseUint1, |_: &Self, x: ExprInst| {Ok(ParseUint0{x})});
|
externfn_impl!(ParseUint1, |_: &Self, x: ExprInst| Ok(ParseUint0{x}));
|
||||||
|
|
||||||
/// Applied ParseUint function
|
/// Applied ParseUint function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/conv/to_string.rs
vendored
2
src/external/conv/to_string.rs
vendored
@@ -11,7 +11,7 @@ use crate::{atomic_impl, atomic_redirect, externfn_impl};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ToString1;
|
pub struct ToString1;
|
||||||
externfn_impl!(ToString1, |_: &Self, x: ExprInst| {Ok(ToString0{x})});
|
externfn_impl!(ToString1, |_: &Self, x: ExprInst| Ok(ToString0{x}));
|
||||||
|
|
||||||
/// Applied ToString function
|
/// Applied ToString function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/cpsio/print.rs
vendored
2
src/external/cpsio/print.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::{Clause, ExprInst};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Print2;
|
pub struct Print2;
|
||||||
externfn_impl!(Print2, |_: &Self, x: ExprInst| {Ok(Print1{x})});
|
externfn_impl!(Print2, |_: &Self, x: ExprInst| Ok(Print1{x}));
|
||||||
|
|
||||||
/// Partially applied Print function
|
/// Partially applied Print function
|
||||||
///
|
///
|
||||||
|
|||||||
5
src/external/cpsio/readline.rs
vendored
5
src/external/cpsio/readline.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::{Clause, ExprInst};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Readln2;
|
pub struct Readln2;
|
||||||
externfn_impl!(Readln2, |_: &Self, x: ExprInst| {Ok(Readln1{x})});
|
externfn_impl!(Readln2, |_: &Self, x: ExprInst| Ok(Readln1{x}));
|
||||||
|
|
||||||
/// Partially applied Readln function
|
/// Partially applied Readln function
|
||||||
///
|
///
|
||||||
@@ -23,7 +23,8 @@ pub struct Readln1{ x: ExprInst }
|
|||||||
atomic_redirect!(Readln1, x);
|
atomic_redirect!(Readln1, x);
|
||||||
atomic_impl!(Readln1, |Self{ x }: &Self| {
|
atomic_impl!(Readln1, |Self{ x }: &Self| {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
stdin().read_line(&mut buf).map_err(|e| RuntimeError::ext(e.to_string(), "reading from stdin"))?;
|
stdin().read_line(&mut buf)
|
||||||
|
.map_err(|e| RuntimeError::ext(e.to_string(), "reading from stdin"))?;
|
||||||
buf.pop();
|
buf.pop();
|
||||||
Ok(Clause::Apply {
|
Ok(Clause::Apply {
|
||||||
f: x.clone(),
|
f: x.clone(),
|
||||||
|
|||||||
2
src/external/num/operators/add.rs
vendored
2
src/external/num/operators/add.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::ExprInst;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Add2;
|
pub struct Add2;
|
||||||
externfn_impl!(Add2, |_: &Self, x: ExprInst| {Ok(Add1{x})});
|
externfn_impl!(Add2, |_: &Self, x: ExprInst| Ok(Add1{x}));
|
||||||
|
|
||||||
/// Partially applied Add function
|
/// Partially applied Add function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/num/operators/divide.rs
vendored
2
src/external/num/operators/divide.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::ExprInst;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Divide2;
|
pub struct Divide2;
|
||||||
externfn_impl!(Divide2, |_: &Self, x: ExprInst| {Ok(Divide1{x})});
|
externfn_impl!(Divide2, |_: &Self, x: ExprInst| Ok(Divide1{x}));
|
||||||
|
|
||||||
/// Partially applied Divide function
|
/// Partially applied Divide function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/num/operators/multiply.rs
vendored
2
src/external/num/operators/multiply.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::ExprInst;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Multiply2;
|
pub struct Multiply2;
|
||||||
externfn_impl!(Multiply2, |_: &Self, x: ExprInst| {Ok(Multiply1{x})});
|
externfn_impl!(Multiply2, |_: &Self, x: ExprInst| Ok(Multiply1{x}));
|
||||||
|
|
||||||
/// Partially applied Multiply function
|
/// Partially applied Multiply function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/num/operators/remainder.rs
vendored
2
src/external/num/operators/remainder.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::ExprInst;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Remainder2;
|
pub struct Remainder2;
|
||||||
externfn_impl!(Remainder2, |_: &Self, x: ExprInst| {Ok(Remainder1{x})});
|
externfn_impl!(Remainder2, |_: &Self, x: ExprInst| Ok(Remainder1{x}));
|
||||||
|
|
||||||
/// Partially applied Remainder function
|
/// Partially applied Remainder function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/num/operators/subtract.rs
vendored
2
src/external/num/operators/subtract.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::ExprInst;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Subtract2;
|
pub struct Subtract2;
|
||||||
externfn_impl!(Subtract2, |_: &Self, x: ExprInst| {Ok(Subtract1{x})});
|
externfn_impl!(Subtract2, |_: &Self, x: ExprInst| Ok(Subtract1{x}));
|
||||||
|
|
||||||
/// Partially applied Subtract function
|
/// Partially applied Subtract function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/str/char_at.rs
vendored
2
src/external/str/char_at.rs
vendored
@@ -12,7 +12,7 @@ use crate::representations::interpreted::{Clause, ExprInst};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CharAt2;
|
pub struct CharAt2;
|
||||||
externfn_impl!(CharAt2, |_: &Self, x: ExprInst| {Ok(CharAt1{x})});
|
externfn_impl!(CharAt2, |_: &Self, x: ExprInst| Ok(CharAt1{x}));
|
||||||
|
|
||||||
/// Partially applied CharAt function
|
/// Partially applied CharAt function
|
||||||
///
|
///
|
||||||
|
|||||||
2
src/external/str/concatenate.rs
vendored
2
src/external/str/concatenate.rs
vendored
@@ -11,7 +11,7 @@ use crate::representations::interpreted::{Clause, ExprInst};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Concatenate2;
|
pub struct Concatenate2;
|
||||||
externfn_impl!(Concatenate2, |_: &Self, c: ExprInst| {Ok(Concatenate1{c})});
|
externfn_impl!(Concatenate2, |_: &Self, c: ExprInst| Ok(Concatenate1{c}));
|
||||||
|
|
||||||
/// Partially applied Concatenate function
|
/// Partially applied Concatenate function
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
use std::error::Error;
|
||||||
use std::fmt::{Display, Debug};
|
use std::fmt::{Display, Debug};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -11,10 +12,16 @@ use crate::representations::Primitive;
|
|||||||
pub use crate::representations::interpreted::Clause;
|
pub use crate::representations::interpreted::Clause;
|
||||||
use crate::representations::interpreted::ExprInst;
|
use crate::representations::interpreted::ExprInst;
|
||||||
|
|
||||||
|
pub struct AtomicReturn {
|
||||||
|
pub clause: Clause,
|
||||||
|
pub gas: Option<usize>,
|
||||||
|
pub inert: bool
|
||||||
|
}
|
||||||
|
|
||||||
// Aliases for concise macros
|
// Aliases for concise macros
|
||||||
pub type RcError = Rc<dyn ExternError>;
|
pub type RcError = Rc<dyn ExternError>;
|
||||||
pub type AtomicResult = Result<(Clause, Option<usize>), RuntimeError>;
|
pub type AtomicResult = Result<AtomicReturn, RuntimeError>;
|
||||||
pub type XfnResult = Result<(Clause, Option<usize>), RcError>;
|
pub type XfnResult = Result<Clause, RcError>;
|
||||||
pub type RcExpr = ExprInst;
|
pub type RcExpr = ExprInst;
|
||||||
|
|
||||||
pub trait ExternError: Display {
|
pub trait ExternError: Display {
|
||||||
@@ -24,6 +31,14 @@ pub trait ExternError: Display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for dyn ExternError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{self}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for dyn ExternError {}
|
||||||
|
|
||||||
/// Represents an externally defined function from the perspective of
|
/// Represents an externally defined function from the perspective of
|
||||||
/// the executor. Since Orchid lacks basic numerical operations,
|
/// the executor. Since Orchid lacks basic numerical operations,
|
||||||
/// these are also external functions.
|
/// these are also external functions.
|
||||||
@@ -85,6 +100,9 @@ impl Atom {
|
|||||||
self.data().as_any().downcast_ref()
|
self.data().as_any().downcast_ref()
|
||||||
.expect("Type mismatch on Atom::cast")
|
.expect("Type mismatch on Atom::cast")
|
||||||
}
|
}
|
||||||
|
pub fn run(&self, ctx: Context) -> AtomicResult {
|
||||||
|
self.0.run(ctx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Atom {
|
impl Clone for Atom {
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ macro_rules! atomic_impl {
|
|||||||
AsRef<$crate::foreign::RcExpr>
|
AsRef<$crate::foreign::RcExpr>
|
||||||
>::as_ref(self).clone();
|
>::as_ref(self).clone();
|
||||||
// run the expression
|
// run the expression
|
||||||
let ret = $crate::interpreter::run(expr, ctx)?;
|
let ret = $crate::interpreter::run(expr, ctx.clone())?;
|
||||||
let $crate::interpreter::Return{ gas, state } = ret;
|
let $crate::interpreter::Return{ gas, state, inert } = ret;
|
||||||
// rebuild the atomic
|
// rebuild the atomic
|
||||||
let next_self = <Self as
|
let next_self = <Self as
|
||||||
From<(&Self, $crate::foreign::RcExpr)>
|
From<(&Self, $crate::foreign::RcExpr)>
|
||||||
>::from((self, state));
|
>::from((self, state));
|
||||||
// branch off or wrap up
|
// branch off or wrap up
|
||||||
let next_clause = if gas.map(|g| g > 0).unwrap_or(true) {
|
let clause = if inert {
|
||||||
match ($next_phase)(&next_self) {
|
match ($next_phase)(&next_self) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => return Err(
|
Err(e) => return Err(
|
||||||
@@ -72,7 +72,7 @@ macro_rules! atomic_impl {
|
|||||||
}
|
}
|
||||||
} else { next_self.to_atom_cls() };
|
} else { next_self.to_atom_cls() };
|
||||||
// package and return
|
// package and return
|
||||||
Ok((next_clause, gas))
|
Ok($crate::foreign::AtomicReturn{ clause, gas, inert: false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ macro_rules! atomic_inert {
|
|||||||
fn run(&self, ctx: $crate::interpreter::Context)
|
fn run(&self, ctx: $crate::interpreter::Context)
|
||||||
-> $crate::foreign::AtomicResult
|
-> $crate::foreign::AtomicResult
|
||||||
{
|
{
|
||||||
Ok((self.clone().to_atom_cls(), ctx.gas))
|
Ok($crate::foreign::AtomicReturn{
|
||||||
|
clause: self.clone().to_atom_cls(),
|
||||||
|
gas: ctx.gas,
|
||||||
|
inert: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,17 +23,16 @@ macro_rules! externfn_impl {
|
|||||||
fn name(&self) -> &str {stringify!($typ)}
|
fn name(&self) -> &str {stringify!($typ)}
|
||||||
fn apply(&self,
|
fn apply(&self,
|
||||||
arg: $crate::foreign::RcExpr,
|
arg: $crate::foreign::RcExpr,
|
||||||
ctx: $crate::interpreter::Context
|
_ctx: $crate::interpreter::Context
|
||||||
) -> $crate::foreign::XfnResult {
|
) -> $crate::foreign::XfnResult {
|
||||||
match ($next_atomic)(self, arg) { // ? casts the result but we want to strictly forward it
|
match ($next_atomic)(self, arg) { // ? casts the result but we want to strictly forward it
|
||||||
Ok(r) => Ok((
|
Ok(r) => Ok(
|
||||||
$crate::representations::interpreted::Clause::P(
|
$crate::representations::interpreted::Clause::P(
|
||||||
$crate::representations::Primitive::Atom(
|
$crate::representations::Primitive::Atom(
|
||||||
$crate::foreign::Atom::new(r)
|
$crate::foreign::Atom::new(r)
|
||||||
)
|
)
|
||||||
),
|
)
|
||||||
ctx.gas.map(|g| g - 1)
|
),
|
||||||
)),
|
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::foreign::Atom;
|
use crate::foreign::AtomicReturn;
|
||||||
use crate::representations::Primitive;
|
use crate::representations::Primitive;
|
||||||
use crate::representations::PathSet;
|
use crate::representations::PathSet;
|
||||||
use crate::representations::interpreted::{ExprInst, Clause};
|
use crate::representations::interpreted::{ExprInst, Clause};
|
||||||
@@ -19,18 +19,18 @@ fn map_at<E>(
|
|||||||
source.try_update(|value| {
|
source.try_update(|value| {
|
||||||
// Pass right through lambdas
|
// Pass right through lambdas
|
||||||
if let Clause::Lambda { args, body } = value {
|
if let Clause::Lambda { args, body } = value {
|
||||||
return Ok(Clause::Lambda {
|
return Ok((Clause::Lambda {
|
||||||
args: args.clone(),
|
args: args.clone(),
|
||||||
body: map_at(path, body.clone(), mapper)?
|
body: map_at(path, body.clone(), mapper)?
|
||||||
})
|
}, ()))
|
||||||
}
|
}
|
||||||
// If the path ends here, process the next (non-lambda) node
|
// If the path ends here, process the next (non-lambda) node
|
||||||
let (head, tail) = if let Some(sf) = path.split_first() {sf} else {
|
let (head, tail) = if let Some(sf) = path.split_first() {sf} else {
|
||||||
return Ok(mapper(value)?)
|
return Ok((mapper(value)?, ()))
|
||||||
};
|
};
|
||||||
// If it's an Apply, execute the next step in the path
|
// If it's an Apply, execute the next step in the path
|
||||||
if let Clause::Apply { f, x } = value {
|
if let Clause::Apply { f, x } = value {
|
||||||
return Ok(match head {
|
return Ok((match head {
|
||||||
Side::Left => Clause::Apply {
|
Side::Left => Clause::Apply {
|
||||||
f: map_at(tail, f.clone(), mapper)?,
|
f: map_at(tail, f.clone(), mapper)?,
|
||||||
x: x.clone(),
|
x: x.clone(),
|
||||||
@@ -39,10 +39,10 @@ fn map_at<E>(
|
|||||||
f: f.clone(),
|
f: f.clone(),
|
||||||
x: map_at(tail, x.clone(), mapper)?,
|
x: map_at(tail, x.clone(), mapper)?,
|
||||||
}
|
}
|
||||||
})
|
}, ()))
|
||||||
}
|
}
|
||||||
panic!("Invalid path")
|
panic!("Invalid path")
|
||||||
})
|
}).map(|p| p.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn substitute(paths: &PathSet, value: Clause, body: ExprInst) -> ExprInst {
|
fn substitute(paths: &PathSet, value: Clause, body: ExprInst) -> ExprInst {
|
||||||
@@ -64,15 +64,14 @@ fn substitute(paths: &PathSet, value: Clause, body: ExprInst) -> ExprInst {
|
|||||||
/// Apply a function-like expression to a parameter.
|
/// Apply a function-like expression to a parameter.
|
||||||
/// If any work is being done, gas will be deducted.
|
/// If any work is being done, gas will be deducted.
|
||||||
pub fn apply(
|
pub fn apply(
|
||||||
f: ExprInst, x: ExprInst, mut ctx: Context
|
f: ExprInst, x: ExprInst, ctx: Context
|
||||||
) -> Result<Return, RuntimeError> {
|
) -> Result<Return, RuntimeError> {
|
||||||
let state = f.clone().try_update(|clause| match clause {
|
let (state, (gas, inert)) = f.clone().try_update(|clause| match clause {
|
||||||
// apply an ExternFn or an internal function
|
// apply an ExternFn or an internal function
|
||||||
Clause::P(Primitive::ExternFn(f)) => {
|
Clause::P(Primitive::ExternFn(f)) => {
|
||||||
let (clause, gas) = f.apply(x, ctx.clone())
|
let clause = f.apply(x, ctx.clone())
|
||||||
.map_err(|e| RuntimeError::Extern(e))?;
|
.map_err(|e| RuntimeError::Extern(e))?;
|
||||||
ctx.gas = gas.map(|g| g - 1); // cost of extern call
|
Ok((clause, (ctx.gas.map(|g| g - 1), false)))
|
||||||
Ok(clause)
|
|
||||||
}
|
}
|
||||||
Clause::Lambda{args, body} => Ok(if let Some(args) = args {
|
Clause::Lambda{args, body} => Ok(if let Some(args) = args {
|
||||||
let x_cls = x.expr().clause.clone();
|
let x_cls = x.expr().clause.clone();
|
||||||
@@ -80,25 +79,22 @@ pub fn apply(
|
|||||||
let new_xpr = new_xpr_inst.expr();
|
let new_xpr = new_xpr_inst.expr();
|
||||||
// cost of substitution
|
// cost of substitution
|
||||||
// XXX: should this be the number of occurrences instead?
|
// XXX: should this be the number of occurrences instead?
|
||||||
ctx.gas = ctx.gas.map(|x| x - 1);
|
(new_xpr.clause.clone(), (ctx.gas.map(|x| x - 1), false))
|
||||||
new_xpr.clause.clone()
|
} else {(body.expr().clause.clone(), (ctx.gas, false))}),
|
||||||
} else {body.expr().clause.clone()}),
|
|
||||||
Clause::Constant(name) => {
|
Clause::Constant(name) => {
|
||||||
let symval = ctx.symbols.get(name).expect("missing symbol for function").clone();
|
let symval = ctx.symbols.get(name).expect("missing symbol for function").clone();
|
||||||
ctx.gas = ctx.gas.map(|x| x - 1); // cost of lookup
|
Ok((Clause::Apply { f: symval, x, }, (ctx.gas, false)))
|
||||||
Ok(Clause::Apply { f: symval, x, })
|
|
||||||
}
|
}
|
||||||
Clause::P(Primitive::Atom(Atom(atom))) => { // take a step in expanding atom
|
Clause::P(Primitive::Atom(atom)) => { // take a step in expanding atom
|
||||||
let (clause, gas) = atom.run(ctx.clone())?;
|
let AtomicReturn { clause, gas, inert } = atom.run(ctx.clone())?;
|
||||||
ctx.gas = gas.map(|x| x - 1); // cost of dispatch
|
Ok((Clause::Apply { f: clause.wrap(), x }, (gas, inert)))
|
||||||
Ok(Clause::Apply { f: clause.wrap(), x })
|
|
||||||
},
|
},
|
||||||
Clause::Apply{ f: fun, x: arg } => { // take a step in resolving pre-function
|
Clause::Apply{ f: fun, x: arg } => { // take a step in resolving pre-function
|
||||||
let res = apply(fun.clone(), arg.clone(), ctx.clone())?;
|
let ret = apply(fun.clone(), arg.clone(), ctx.clone())?;
|
||||||
ctx.gas = res.gas; // if work has been done, it has been paid
|
let Return { state, inert, gas } = ret;
|
||||||
Ok(Clause::Apply{ f: res.state, x })
|
Ok((Clause::Apply{ f: state, x }, (gas, inert)))
|
||||||
},
|
},
|
||||||
_ => Err(RuntimeError::NonFunctionApplication(f.clone()))
|
_ => Err(RuntimeError::NonFunctionApplication(f.clone()))
|
||||||
})?;
|
})?;
|
||||||
Ok(Return { state, gas: ctx.gas })
|
Ok(Return { state, gas, inert })
|
||||||
}
|
}
|
||||||
@@ -24,4 +24,5 @@ impl Context<'_> {
|
|||||||
pub struct Return {
|
pub struct Return {
|
||||||
pub state: ExprInst,
|
pub state: ExprInst,
|
||||||
pub gas: Option<usize>,
|
pub gas: Option<usize>,
|
||||||
|
pub inert: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::representations::interpreted::ExprInst;
|
|||||||
use crate::foreign::ExternError;
|
use crate::foreign::ExternError;
|
||||||
|
|
||||||
/// Problems in the process of execution
|
/// Problems in the process of execution
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum RuntimeError {
|
pub enum RuntimeError {
|
||||||
Extern(Rc<dyn ExternError>),
|
Extern(Rc<dyn ExternError>),
|
||||||
NonFunctionApplication(ExprInst),
|
NonFunctionApplication(ExprInst),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::foreign::Atom;
|
use crate::foreign::AtomicReturn;
|
||||||
use crate::representations::Primitive;
|
use crate::representations::Primitive;
|
||||||
use crate::representations::interpreted::{Clause, ExprInst};
|
use crate::representations::interpreted::{Clause, ExprInst};
|
||||||
|
|
||||||
@@ -9,19 +9,20 @@ use super::context::{Context, Return};
|
|||||||
pub fn run(expr: ExprInst, mut ctx: Context)
|
pub fn run(expr: ExprInst, mut ctx: Context)
|
||||||
-> Result<Return, RuntimeError>
|
-> Result<Return, RuntimeError>
|
||||||
{
|
{
|
||||||
let state = expr.try_normalize(|cls| -> Result<Clause, RuntimeError> {
|
let (state, (gas, inert)) = expr.try_normalize(|cls| -> Result<(Clause, _), RuntimeError> {
|
||||||
let mut i = cls.clone();
|
let mut i = cls.clone();
|
||||||
while ctx.gas.map(|g| g > 0).unwrap_or(true) {
|
while ctx.gas.map(|g| g > 0).unwrap_or(true) {
|
||||||
match &i {
|
match &i {
|
||||||
Clause::Apply { f, x } => {
|
Clause::Apply { f, x } => {
|
||||||
let res = apply(f.clone(), x.clone(), ctx.clone())?;
|
let res = apply(f.clone(), x.clone(), ctx.clone())?;
|
||||||
if ctx.is_stuck(res.gas) {return Ok(i)}
|
if res.inert {return Ok((i, (res.gas, true)))}
|
||||||
ctx.gas = res.gas;
|
ctx.gas = res.gas;
|
||||||
i = res.state.expr().clause.clone();
|
i = res.state.expr().clause.clone();
|
||||||
}
|
}
|
||||||
Clause::P(Primitive::Atom(Atom(data))) => {
|
Clause::P(Primitive::Atom(data)) => {
|
||||||
let (clause, gas) = data.run(ctx.clone())?;
|
let ret = data.run(ctx.clone())?;
|
||||||
if ctx.is_stuck(gas) {return Ok(i)}
|
let AtomicReturn { clause, gas, inert } = ret;
|
||||||
|
if inert {return Ok((i, (gas, true)))}
|
||||||
ctx.gas = gas;
|
ctx.gas = gas;
|
||||||
i = clause.clone();
|
i = clause.clone();
|
||||||
}
|
}
|
||||||
@@ -30,10 +31,12 @@ pub fn run(expr: ExprInst, mut ctx: Context)
|
|||||||
ctx.gas = ctx.gas.map(|g| g - 1); // cost of lookup
|
ctx.gas = ctx.gas.map(|g| g - 1); // cost of lookup
|
||||||
i = symval.expr().clause.clone();
|
i = symval.expr().clause.clone();
|
||||||
}
|
}
|
||||||
_ => return Ok(i)
|
// non-reducible
|
||||||
|
_ => return Ok((i, (ctx.gas, true)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(i)
|
// out of gas
|
||||||
|
Ok((i, (ctx.gas, false)))
|
||||||
})?;
|
})?;
|
||||||
Ok(Return { state, gas: ctx.gas })
|
Ok(Return { state, gas, inert })
|
||||||
}
|
}
|
||||||
@@ -56,26 +56,27 @@ impl ExprInst {
|
|||||||
/// Call a normalization function on the expression. The expr is
|
/// Call a normalization function on the expression. The expr is
|
||||||
/// updated with the new clause which affects all copies of it
|
/// updated with the new clause which affects all copies of it
|
||||||
/// across the tree.
|
/// across the tree.
|
||||||
pub fn try_normalize<E>(&self,
|
pub fn try_normalize<T, E>(&self,
|
||||||
mapper: impl FnOnce(&Clause) -> Result<Clause, E>
|
mapper: impl FnOnce(&Clause) -> Result<(Clause, T), E>
|
||||||
) -> Result<Self, E> {
|
) -> Result<(Self, T), E> {
|
||||||
let new_clause = mapper(&self.expr().clause)?;
|
let (new_clause, extra) = mapper(&self.expr().clause)?;
|
||||||
self.expr_mut().clause = new_clause;
|
self.expr_mut().clause = new_clause;
|
||||||
Ok(self.clone())
|
Ok((self.clone(), extra))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a mutation function on the expression, producing a new,
|
/// Run a mutation function on the expression, producing a new,
|
||||||
/// distinct expression. The new expression shares location info with
|
/// distinct expression. The new expression shares location info with
|
||||||
/// the original but is normalized independently.
|
/// the original but is normalized independently.
|
||||||
pub fn try_update<E>(&self,
|
pub fn try_update<T, E>(&self,
|
||||||
mapper: impl FnOnce(&Clause) -> Result<Clause, E>
|
mapper: impl FnOnce(&Clause) -> Result<(Clause, T), E>
|
||||||
) -> Result<Self, E> {
|
) -> Result<(Self, T), E> {
|
||||||
let expr = self.expr();
|
let expr = self.expr();
|
||||||
|
let (clause, extra) = mapper(&expr.clause)?;
|
||||||
let new_expr = Expr{
|
let new_expr = Expr{
|
||||||
clause: mapper(&expr.clause)?,
|
clause,
|
||||||
location: expr.location.clone(),
|
location: expr.location.clone(),
|
||||||
};
|
};
|
||||||
Ok(Self(Rc::new(RefCell::new(new_expr))))
|
Ok((Self(Rc::new(RefCell::new(new_expr))), extra))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call a predicate on the expression, returning whatever the
|
/// Call a predicate on the expression, returning whatever the
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ fn scal_cnt<'a>(iter: impl Iterator<Item = &'a Expr>) -> usize {
|
|||||||
/// Recursively convert this pattern into a matcher that can be
|
/// Recursively convert this pattern into a matcher that can be
|
||||||
/// efficiently applied to slices.
|
/// efficiently applied to slices.
|
||||||
pub fn mk_matcher(pattern: &[Expr]) -> AnyMatcher {
|
pub fn mk_matcher(pattern: &[Expr]) -> AnyMatcher {
|
||||||
println!("matcher from {:?}", pattern);
|
|
||||||
let left_split = scal_cnt(pattern.iter());
|
let left_split = scal_cnt(pattern.iter());
|
||||||
if pattern.len() <= left_split {
|
if pattern.len() <= left_split {
|
||||||
return AnyMatcher::Scalar(mk_scalv(pattern))
|
return AnyMatcher::Scalar(mk_scalv(pattern))
|
||||||
@@ -51,13 +50,11 @@ pub fn mk_matcher(pattern: &[Expr]) -> AnyMatcher {
|
|||||||
|
|
||||||
/// Pattern MUST NOT contain vectorial placeholders
|
/// Pattern MUST NOT contain vectorial placeholders
|
||||||
fn mk_scalv(pattern: &[Expr]) -> Vec<ScalMatcher> {
|
fn mk_scalv(pattern: &[Expr]) -> Vec<ScalMatcher> {
|
||||||
println!("Scalv from {:?}", pattern);
|
|
||||||
pattern.iter().map(mk_scalar).collect()
|
pattern.iter().map(mk_scalar).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern MUST start and end with a vectorial placeholder
|
/// Pattern MUST start and end with a vectorial placeholder
|
||||||
fn mk_vec(pattern: &[Expr]) -> VecMatcher {
|
fn mk_vec(pattern: &[Expr]) -> VecMatcher {
|
||||||
println!("Vec from {:?}", pattern);
|
|
||||||
debug_assert!(!pattern.is_empty(), "pattern cannot be empty");
|
debug_assert!(!pattern.is_empty(), "pattern cannot be empty");
|
||||||
debug_assert!(pattern.first().map(vec_attrs).is_some(), "pattern must start with a vectorial");
|
debug_assert!(pattern.first().map(vec_attrs).is_some(), "pattern must start with a vectorial");
|
||||||
debug_assert!(pattern.last().map(vec_attrs).is_some(), "pattern must end with a vectorial");
|
debug_assert!(pattern.last().map(vec_attrs).is_some(), "pattern must end with a vectorial");
|
||||||
@@ -103,7 +100,6 @@ fn mk_vec(pattern: &[Expr]) -> VecMatcher {
|
|||||||
|
|
||||||
/// Pattern MUST NOT be a vectorial placeholder
|
/// Pattern MUST NOT be a vectorial placeholder
|
||||||
fn mk_scalar(pattern: &Expr) -> ScalMatcher {
|
fn mk_scalar(pattern: &Expr) -> ScalMatcher {
|
||||||
println!("Scalar from {:?}", pattern);
|
|
||||||
match &pattern.value {
|
match &pattern.value {
|
||||||
Clause::P(p) => ScalMatcher::P(p.clone()),
|
Clause::P(p) => ScalMatcher::P(p.clone()),
|
||||||
Clause::Name(n) => ScalMatcher::Name(*n),
|
Clause::Name(n) => ScalMatcher::Name(*n),
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ pub fn run_dir(dir: &Path) {
|
|||||||
match repo.step(&tree) {
|
match repo.step(&tree) {
|
||||||
None => break tree,
|
None => break tree,
|
||||||
Some(phase) => {
|
Some(phase) => {
|
||||||
// println!("Step {idx}/{macro_timeout}: {}", phase.bundle(&i));
|
println!("Step {idx}/{macro_timeout}: {}", phase.bundle(&i));
|
||||||
tree = phase;
|
tree = phase;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -135,9 +135,16 @@ pub fn run_dir(dir: &Path) {
|
|||||||
.join(", ")
|
.join(", ")
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let Return{ gas, state } = interpreter::run(entrypoint.clone(), ctx)
|
let Return{ gas, state, inert } = interpreter::run(entrypoint.clone(), ctx)
|
||||||
.unwrap_or_else(|e| panic!("Runtime error: {}", e));
|
.unwrap_or_else(|e| panic!("Runtime error: {}", e));
|
||||||
println!("Settled at {}", state.bundle(&i));
|
if inert {
|
||||||
|
println!("Expression not reducible");
|
||||||
|
println!("Settled at {}", state.expr().clause.bundle(&i));
|
||||||
|
println!("Remaining gas: {}",
|
||||||
|
gas.map(|g| g.to_string())
|
||||||
|
.unwrap_or(String::from("∞"))
|
||||||
|
);
|
||||||
|
}
|
||||||
if gas == Some(0) {println!("Ran out of gas!")}
|
if gas == Some(0) {println!("Ran out of gas!")}
|
||||||
else {println!("Expression not reducible.")}
|
else {println!("Expression not reducible.")}
|
||||||
}
|
}
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
use std::sync::{Mutex, Arc};
|
|
||||||
use std::num::NonZeroU32;
|
|
||||||
use std::hash::Hash;
|
|
||||||
|
|
||||||
use lasso::{Rodeo, Spur, Key};
|
|
||||||
use base64::{engine::general_purpose::STANDARD_NO_PAD as BASE64, Engine};
|
|
||||||
|
|
||||||
/// A token representing an interned string or sequence in an interner
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
|
|
||||||
pub struct Token<const RANK: u8>(pub Spur);
|
|
||||||
|
|
||||||
/// An interner that can intern strings, and sequences of things it
|
|
||||||
/// interned as long as they have the same rank
|
|
||||||
pub trait Interner: Sync {
|
|
||||||
fn str2tok(&self, str: &str) -> Token<String>;
|
|
||||||
fn tok2str(&self, token: Token<String>) -> String;
|
|
||||||
fn slc2tok<const RANK: u8>(&self, slice: &[Token<RANK>]) -> Token<{RANK + 1}>;
|
|
||||||
fn tok2slc<const RANK: u8>(&self, token: Token<RANK>) -> Vec<Token<{RANK - 1}>>;
|
|
||||||
fn tok2strv(&self, token: Token<Vec<Token<String>>>) -> Vec<String> {
|
|
||||||
self.tok2slc(token).into_iter().map(|t| self.tok2str(t)).collect()
|
|
||||||
}
|
|
||||||
fn tokv2strv(&self, slice: &[Token<String>]) -> Vec<String> {
|
|
||||||
slice.iter().map(|t| self.tok2str(*t)).collect()
|
|
||||||
}
|
|
||||||
/// Get the first token of a sequence
|
|
||||||
fn head<const RANK: u8>(&self, token: Token<RANK>) -> Token<{RANK - 1}>;
|
|
||||||
/// Returns the length of a sequence
|
|
||||||
fn len<const RANK: u8>(&self, token: Token<RANK>) -> usize
|
|
||||||
where Token<{RANK - 1}>: Clone;
|
|
||||||
/// Returns the length of the longest identical prefix of the two sequences
|
|
||||||
fn coprefix<const RANK: u8>(&self, a: Token<RANK>, b: Token<RANK>) -> usize
|
|
||||||
where Token<{RANK - 1}>: Clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq<const RANK: u8>(seq: &[Token<RANK>]) -> String {
|
|
||||||
let data: Vec<u8> = seq.iter()
|
|
||||||
.map(|t| u32::from(t.0.into_inner()).to_le_bytes().into_iter())
|
|
||||||
.flatten()
|
|
||||||
.collect();
|
|
||||||
BASE64.encode(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_seq<const RANK: u8>(string: &str) -> Vec<Token<RANK>> {
|
|
||||||
let data = BASE64.decode(string)
|
|
||||||
.expect("String is not valid base64");
|
|
||||||
assert!(data.len() % 4 == 0, "Tokens should serialize to 3 bytes each");
|
|
||||||
data.array_chunks::<4>().map(|a| {
|
|
||||||
let bytes = [a[0], a[1], a[2], a[3]];
|
|
||||||
let nz32 = NonZeroU32::new(u32::from_le_bytes(bytes))
|
|
||||||
.expect("Token representation should never be zero");
|
|
||||||
Token(Spur::try_from_usize(u32::from(nz32) as usize).unwrap())
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An interner that delegates the actual work to Lasso
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct LassoInterner {
|
|
||||||
strings: Arc<Mutex<Rodeo>>,
|
|
||||||
slices: Arc<Mutex<Rodeo>>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LassoInterner {
|
|
||||||
/// Create an empty interner. Called to create the singleton.
|
|
||||||
fn new() -> Self {
|
|
||||||
Self{
|
|
||||||
slices: Arc::new(Mutex::new(Rodeo::new())),
|
|
||||||
strings: Arc::new(Mutex::new(Rodeo::new()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Interner for LassoInterner {
|
|
||||||
fn str2tok(&self, str: &str) -> Token<String> {
|
|
||||||
let mut strings = self.strings.lock().unwrap();
|
|
||||||
let key = strings.get_or_intern(str);
|
|
||||||
Token(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tok2str<'a>(&'a self, token: Token<String>) -> String {
|
|
||||||
let key = token.0;
|
|
||||||
let strings = self.strings.lock().unwrap();
|
|
||||||
strings.resolve(&key).to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slc2tok<const RANK: u8>(&self, slice: &[Token<RANK>]) -> Token<{RANK + 1}> {
|
|
||||||
let data = serialize_seq(slice);
|
|
||||||
let mut slices = self.slices.lock().unwrap();
|
|
||||||
let key = slices.get_or_intern(data);
|
|
||||||
Token(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tok2slc<'a, const RANK: u8>(&'a self, token: Token<RANK>) -> Vec<Token<{RANK - 1}>> {
|
|
||||||
let key = token.0;
|
|
||||||
let slices = self.slices.lock().unwrap();
|
|
||||||
let string = slices.resolve(&key);
|
|
||||||
deserialize_seq(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn head<const RANK: u8>(&self, token: Token<RANK>) -> Token<{RANK - 1}> {
|
|
||||||
let key = token.0;
|
|
||||||
let slices = self.slices.lock().unwrap();
|
|
||||||
let string = slices.resolve(&key);
|
|
||||||
deserialize_seq(&string[0..5])[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn len<const RANK: u8>(&self, token: Token<RANK>) -> usize where Token<{RANK - 1}>: Clone {
|
|
||||||
let key = token.0;
|
|
||||||
let slices = self.slices.lock().unwrap();
|
|
||||||
let string = slices.resolve(&key);
|
|
||||||
assert!(string.len() % 4 == 0, "Tokens should serialize to 3 characters");
|
|
||||||
string.len() / 4
|
|
||||||
}
|
|
||||||
|
|
||||||
fn coprefix<const RANK: u8>(&self, a: Token<RANK>, b: Token<RANK>) -> usize where Token<{RANK - 1}>: Clone {
|
|
||||||
let keya = a.0;
|
|
||||||
let keyb = b.0;
|
|
||||||
let slices = self.slices.lock().unwrap();
|
|
||||||
let sa = slices.resolve(&keya);
|
|
||||||
let sb = slices.resolve(&keyb);
|
|
||||||
sa.bytes()
|
|
||||||
.zip(sb.bytes())
|
|
||||||
.take_while(|(a, b)| a == b)
|
|
||||||
.count() / 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create an interner that inherits the singleton's data, and
|
|
||||||
/// block all future interaction with the singleton.
|
|
||||||
///
|
|
||||||
/// DO NOT call within [dynamic] or elsewhere pre-main
|
|
||||||
pub fn mk_interner() -> impl Interner {
|
|
||||||
LassoInterner::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait StringLike: Clone + Eq + Hash {
|
|
||||||
fn into_str(self, i: &Interner) -> String;
|
|
||||||
fn into_tok(self, i: &Interner) -> Token<String>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StringLike for String {
|
|
||||||
fn into_str(self, _i: &Interner) -> String {self}
|
|
||||||
fn into_tok(self, i: &Interner) -> Token<String> {i.str2tok(&self)}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StringLike for Token<String> {
|
|
||||||
fn into_str(self, i: &Interner) -> String {i.tok2str(self)}
|
|
||||||
fn into_tok(self, _i: &Interner) -> Token<String> {self}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait StringVLike: Clone + Eq + Hash {
|
|
||||||
fn into_strv(self, i: &Interner) -> Vec<String>;
|
|
||||||
fn into_tok(self, i: &Interner) -> Token<Vec<Token<String>>>;
|
|
||||||
fn into_tokv(self, i: &Interner) -> Vec<Token<String>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StringVLike for Vec<String> {
|
|
||||||
fn into_strv(self, _i: &Interner) -> Vec<String> {self}
|
|
||||||
fn into_tok(self, i: &Interner) -> Token<Vec<Token<String>>> {
|
|
||||||
let tokv = self.into_iter()
|
|
||||||
.map(|s| i.str2tok(&s))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
i.slc2tok(&tokv)
|
|
||||||
}
|
|
||||||
fn into_tokv(self, i: &Interner) -> Vec<Token<String>> {
|
|
||||||
self.into_iter()
|
|
||||||
.map(|s| i.str2tok(&s))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StringVLike for Vec<Token<String>> {
|
|
||||||
fn into_strv(self, i: &Interner) -> Vec<String> {i.tokv2strv(&self)}
|
|
||||||
fn into_tok(self, i: &Interner) -> Token<Vec<Token<String>>> {i.slc2tok(&self)}
|
|
||||||
fn into_tokv(self, _i: &Interner) -> Vec<Token<String>> {self}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StringVLike for Token<Vec<Token<String>>> {
|
|
||||||
fn into_strv(self, i: &Interner) -> Vec<String> {i.tok2strv(self)}
|
|
||||||
fn into_tok(self, _i: &Interner) -> Token<Vec<Token<String>>> {self}
|
|
||||||
fn into_tokv(self, i: &Interner) -> Vec<Token<String>> {i.tok2slc(self)}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user