Reorganize naming scheme

This commit is contained in:
2023-12-10 12:50:44 -05:00
parent 3f3ea56375
commit b40c928026
17 changed files with 325 additions and 939 deletions

902
slj/Cargo.lock generated Normal file
View File

@@ -0,0 +1,902 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
[[package]]
name = "ascii-canvas"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
dependencies = [
"term",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4fdf311b2564edbf43d3a06335d309814f6ec60f55d090885d68e1a2e664c04"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
]
[[package]]
name = "cranelift-bforest"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b5bb9245ec7dcc04d03110e538d31f0969d301c9d673145f4b4d5c3478539a3"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebb18d10e5ddac43ba4ca8fd4e310938569c3e484cc01b6372b27dc5bb4dfd28"
dependencies = [
"bumpalo",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-control",
"cranelift-entity",
"cranelift-isle",
"gimli",
"hashbrown 0.14.2",
"log",
"regalloc2",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a3ce6d22982c1b9b6b012654258bab1a13947bb12703518bef06b1a4867c3d6"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47220fd4f9a0ce23541652b6f16f83868d282602c600d14934b2a4c166b4bd80"
[[package]]
name = "cranelift-control"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5a4c42672aea9b6e820046b52e47a1c05d3394a6cdf4cb3c3c4b702f954bd2"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b4e9a3296fc827f9d35135dc2c0c8dd8d8359eb1ef904bae2d55d5bcb0c9f94"
[[package]]
name = "cranelift-frontend"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ec537d0f0b8e084517f3e7bfa1d89af343d7c7df455573fca9f272d4e01267"
dependencies = [
"cranelift-codegen",
"log",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-isle"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45bab6d69919d210a50331d35cc6ce111567bc040aebac63a8ae130d0400a075"
[[package]]
name = "cranelift-jit"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1daca8224e77263494e1d949daeb0a0a0992f9c489d4dc395bfc8ddda0eafcaf"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
"cranelift-entity",
"cranelift-module",
"cranelift-native",
"libc",
"log",
"region",
"target-lexicon",
"wasmtime-jit-icache-coherence",
"windows-sys",
]
[[package]]
name = "cranelift-module"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533ebbad90a77980bdbbe6bd4beee9598a74db06316e8a9def7a6d9564e19f5e"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
]
[[package]]
name = "cranelift-native"
version = "0.101.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f32e81605f352cf37af5463f11cd7deec7b6572741931a8d372f7fdd4a744f5d"
dependencies = [
"cranelift-codegen",
"libc",
"target-lexicon",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "ena"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1"
dependencies = [
"log",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "fallible-iterator"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "getrandom"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
dependencies = [
"fallible-iterator",
"indexmap",
"stable_deref_trait",
]
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash",
]
[[package]]
name = "hashbrown"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
[[package]]
name = "hermit-abi"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown 0.14.2",
]
[[package]]
name = "is-terminal"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi",
"rustix",
"windows-sys",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "lalrpop"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8"
dependencies = [
"ascii-canvas",
"bit-set",
"diff",
"ena",
"is-terminal",
"itertools",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax 0.7.5",
"string_cache",
"term",
"tiny-keccak",
"unicode-xid",
]
[[package]]
name = "lalrpop-util"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d"
dependencies = [
"regex",
]
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "libredox"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
dependencies = [
"bitflags 2.4.1",
"libc",
"redox_syscall",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "petgraph"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "phf_shared"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_users"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "regalloc2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6"
dependencies = [
"hashbrown 0.13.2",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax 0.8.2",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.2",
]
[[package]]
name = "regex-syntax"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "region"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0"
dependencies = [
"bitflags 1.3.2",
"libc",
"mach",
"winapi",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.38.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
dependencies = [
"bitflags 2.4.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "sl"
version = "0.1.0"
dependencies = [
"anyhow",
"cranelift",
"cranelift-jit",
"cranelift-module",
"cranelift-native",
"lalrpop",
"lalrpop-util",
"once_cell",
"regex",
]
[[package]]
name = "slice-group-by"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
[[package]]
name = "smallvec"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "string_cache"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
dependencies = [
"new_debug_unreachable",
"once_cell",
"parking_lot",
"phf_shared",
"precomputed-hash",
]
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "target-lexicon"
version = "0.12.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a"
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "14.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f67e6be36375c39cff57ed3b137ab691afbf2d9ba8ee1c01f77888413f218749"
dependencies = [
"cfg-if",
"libc",
"windows-sys",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "zerocopy"
version = "0.7.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

22
slj/Cargo.toml Normal file
View File

@@ -0,0 +1,22 @@
[package]
name = "sl"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.bench]
debug = true
[dependencies]
lalrpop-util = {version="0.20", features=["lexer"]}
regex = "1"
once_cell = "1"
anyhow = "1"
cranelift = "0.101.4"
cranelift-module = "0.101.4"
cranelift-jit = "0.101.4"
cranelift-native = "0.101.4"
[build-dependencies]
lalrpop = "0.20"

5
slj/build.rs Normal file
View File

@@ -0,0 +1,5 @@
extern crate lalrpop;
fn main() {
lalrpop::process_root().unwrap();
}

32
slj/src/grammar.lalrpop Normal file
View File

@@ -0,0 +1,32 @@
use std::str::FromStr;
use std::rc::Rc;
use std::cell::RefCell;
use sl::Form;
grammar;
pub Term: Rc<Form> = {
NUM => Rc::new(Form::Int(i32::from_str(<>).unwrap())),
SYM => Rc::new(Form::Symbol(<>.to_owned(),RefCell::new(None))),
"(" <ListInside?> ")" => <>.unwrap_or(Rc::new(Form::Nil)),
"'" <Term> => Rc::new(Form::Pair(Rc::new(Form::Symbol("quote".to_owned(),RefCell::new(None))), Rc::new(Form::Pair(<>, Rc::new(Form::Nil),RefCell::new(None))),RefCell::new(None))),
"!" <h: Term> <t: Term> => {
h.append(t).unwrap()
},
};
ListInside: Rc<Form> = {
<Term> => Rc::new(Form::Pair(<>, Rc::new(Form::Nil),RefCell::new(None))),
<h: Term> <t: ListInside> => Rc::new(Form::Pair(h, t,RefCell::new(None))),
<a: Term> "." <d: Term> => Rc::new(Form::Pair(a, d,RefCell::new(None))),
}
match {
"(",
")",
".",
"'",
"!",
r"[0-9]+" => NUM,
r"[a-zA-Z+*/_=?%&|^<>-][\w+*/=_?%&|^<>-]*" => SYM,
r"(;[^\n]*\n)|\s+" => { }
}

660
slj/src/lib.rs Normal file
View File

@@ -0,0 +1,660 @@
use std::rc::Rc;
use std::collections::BTreeMap;
use std::fmt;
use std::cell::RefCell;
use anyhow::{anyhow,bail,Result};
// This first Simple Lisp really is
//
// No fexprs, no mutation, no continuations, no macros, no strings.
// Int/Bool/Nil/Pair/Symbol/Closure/Prim.
//
// Figuring out GC between a JIT and Rust will be tricky.
// Can start with a like tracing-JIT-into-bytecode
// Replcing Env with pairs or somesuch would make JIT interop easier I think, because we wouldn't
// have to deal with refcell, but then we would again for mutation.
// Maybe doing all allocation on the Rust side with #[no_mangle] functions would make things easier
// mmmm no let's make our own Box, Rc, maybe Arc
// rustonomicon
// What if we're cute and use the ID
// like we will eventually use value tagging
// like, use the same encoding
// interned symbols and all
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)]
pub struct ID {
id: i64
}
impl fmt::Display for ID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.id)
}
}
#[derive(Debug)]
pub enum Form {
Nil,
Int(i32),
Bool(bool),
Symbol(String, RefCell<Option<ID>>),
Pair(Rc<Form>, Rc<Form>, RefCell<Option<ID>>),
Closure(Vec<String>, Rc<RefCell<Env>>, Rc<Form>, ID),
Prim(Prim),
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum Prim {
Add,
Sub,
Mul,
Div,
Mod,
Eq,
Cons,
Car,
Cdr,
}
impl Form {
fn my_eq(&self, o: &Rc<Form>) -> bool {
match self {
Form::Nil => o.is_nil(),
Form::Int(i) => if let Ok(oi) = o.int() { *i == oi } else { false },
Form::Bool(b) => if let Ok(ob) = o.bool() { *b == ob } else { false },
Form::Symbol(s, _id) => if let Ok(os) = o.sym() { s == os } else { false },
Form::Pair(a,b,_id) => if let Ok((oa,ob)) = o.pair() { a.my_eq(&oa) && b.my_eq(&ob) } else { false },
Form::Closure(_, _, _, _) => false,
Form::Prim(p) => match &**o { Form::Prim(op) => p == op, _ => false },
}
}
fn new_pair(car: Rc<Form>, cdr: Rc<Form>) -> Rc<Form> {
Rc::new(Form::Pair(car, cdr, RefCell::new(None)))
}
fn new_nil() -> Rc<Form> {
Rc::new(Form::Nil)
}
fn new_int(i: i32) -> Rc<Form> {
Rc::new(Form::Int(i))
}
fn new_bool(b: bool) -> Rc<Form> {
Rc::new(Form::Bool(b))
}
fn new_closure(params: Vec<String>, env: Rc<RefCell<Env>>, body: Rc<Form>, ctx: &mut Ctx) -> Rc<Form> {
Rc::new(Form::Closure(params, env, body, ctx.alloc_id()))
}
fn truthy(&self) -> bool {
match self {
Form::Bool(b) => *b,
Form::Nil => false,
_ => true,
}
}
fn bool(&self) -> Result<bool> {
match self {
Form::Bool(b) => Ok(*b),
_ => Err(anyhow!("bool on not a bool")),
}
}
fn int(&self) -> Result<i32> {
match self {
Form::Int(i) => Ok(*i),
_ => Err(anyhow!("int on not a int")),
}
}
fn prim(&self) -> Result<Prim> {
match self {
Form::Prim(p) => Ok(*p),
_ => Err(anyhow!("prim on not a prim")),
}
}
fn sym(&self) -> Result<&str> {
match self {
Form::Symbol(s, _id) => Ok(s),
_ => Err(anyhow!("sym on not a sym")),
}
}
fn pair(&self) -> Result<(Rc<Form>,Rc<Form>)> {
match self {
Form::Pair(car, cdr, _id) => Ok((Rc::clone(car),Rc::clone(cdr))),
_ => Err(anyhow!("pair on not a pair")),
}
}
fn car(&self) -> Result<Rc<Form>> {
match self {
Form::Pair(car, _cdr, _id) => Ok(Rc::clone(car)),
_ => Err(anyhow!("car on not a pair")),
}
}
fn cdr(&self) -> Result<Rc<Form>> {
match self {
Form::Pair(_car, cdr, _id) => Ok(Rc::clone(cdr)),
_ => Err(anyhow!("cdr on not a pair")),
}
}
fn is_nil(&self) -> bool {
match self {
Form::Nil => true,
_ => false,
}
}
pub fn append(&self, x: Rc<Form>) -> Result<Rc<Form>> {
match self {
Form::Pair(car, cdr, _id) => cdr.append(x).map(|x| Rc::new(Form::Pair(Rc::clone(car), x, RefCell::new(None)))),
Form::Nil => Ok(Rc::new(Form::Pair(x, Rc::new(Form::Nil), RefCell::new(None)))),
_ => Err(anyhow!("append to not a pair")),
}
}
}
#[derive(Debug)]
pub struct Env {
u: Option<Rc<RefCell<Env>>>,
// split this into
// BTreeMap<String, usize>
// Vec<usize> so that traced code can refer by index
m: BTreeMap<String, Rc<Form>>
}
impl Env {
pub fn root_env() -> Rc<RefCell<Env>> {
Rc::new(RefCell::new(Env {
u: None,
m: [
("+", Rc::new(Form::Prim(Prim::Add))),
("-", Rc::new(Form::Prim(Prim::Sub))),
("*", Rc::new(Form::Prim(Prim::Mul))),
("/", Rc::new(Form::Prim(Prim::Div))),
("%", Rc::new(Form::Prim(Prim::Mod))),
("cons", Rc::new(Form::Prim(Prim::Cons))),
("cdr", Rc::new(Form::Prim(Prim::Cdr))),
("car", Rc::new(Form::Prim(Prim::Car))),
("=", Rc::new(Form::Prim(Prim::Eq))),
("nil", Form::new_nil()),
].into_iter().map(|(s,p)| (s.to_owned(), p)).collect()
}))
}
pub fn chain(o: &Rc<RefCell<Env>>) -> Rc<RefCell<Env>> {
Rc::new(RefCell::new(Env {
u: Some(Rc::clone(o)),
m: BTreeMap::new(),
}))
}
pub fn lookup(&self, s: &str) -> Result<Rc<Form>> {
if let Some(r) = self.m.get(s) {
Ok(Rc::clone(r))
} else if let Some(u) = &self.u {
u.borrow().lookup(s)
} else {
bail!("lookup of {s} failed")
}
}
pub fn define(&mut self, s: String, v: Rc<Form>) {
// no mutation, shadowing in inner scope ok
assert!(!self.m.contains_key(&s));
self.m.insert(s, v);
}
}
#[derive(Debug)]
enum Op {
Guard { const_value: Rc<Form>, side: (Option<Rc<Form>>, Rc<Cont>) },
Debug,
Define { sym: String },
Const { con: Rc<Form> },
Lookup { sym: String },
Call(Vec<usize>),
Loop(Vec<usize>),
Return,
}
impl fmt::Display for Op {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Op::Guard { const_value, side } => write!(f, "Guard({const_value})"),
Op::Debug => write!(f, "Debug"),
Op::Define { sym } => write!(f, "Define({sym})"),
Op::Const { con } => write!(f, "Const_{con}"),
Op::Lookup { sym } => write!(f, "Lookup({sym})"),
Op::Call(params) => write!(f, "Call({:?})", params),
Op::Loop(params) => write!(f, "Loop({:?})", params),
Op::Return => write!(f, "Return"),
}
}
}
#[derive(Debug)]
struct Trace {
id: ID,
// needs to track which are constants
ops: Vec<Op>,
param_stack: Vec<usize>,
}
impl Trace {
fn new(id: ID) -> Self {
Trace { id, ops: vec![], param_stack: vec![] }
}
}
impl fmt::Display for Trace {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Trace for {} [", self.id)?;
for op in &self.ops {
write!(f, " {}", op)?;
}
write!(f, " ]")?;
if !self.param_stack.is_empty() {
write!(f, "[")?;
for s in &self.param_stack {
write!(f, " {}", s)?;
}
write!(f, " ]")?;
}
Ok(())
}
}
#[derive(Debug)]
struct Ctx {
id_counter: i64,
func_calls: BTreeMap<ID, i64>,
tracing: Option<Trace>,
traces: BTreeMap<ID, Trace>,
}
impl fmt::Display for Ctx {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Ctx")
}
}
impl Ctx {
fn new() -> Ctx {
Ctx {
id_counter: 0,
func_calls: BTreeMap::new(),
tracing: None,
traces: BTreeMap::new(),
}
}
fn alloc_id(&mut self) -> ID {
self.id_counter += 1;
ID { id: self.id_counter }
}
fn trace_running(&self) -> bool { self.tracing.is_some() }
fn trace_call_bit(&mut self) {
if let Some(trace) = &mut self.tracing {
trace.param_stack.push(trace.ops.len()-1);
}
}
// Though I guess that means call start should recieve the parameters
// also, for like variables, it should guard on what function
// if dynamic, interacts with the constant tracking
// 7 options
// - not tracing, closure - do stats
// - not tracing, prim - do nothing
// - tracing, Constant Prim - inline prim
// - tracing, Constant Closure - inline call
// - tracing, Static, tail-self - emit loop
// - tracing, Static,nontail-self- emit call
// - tracing, Dynamic, other - emit call
//
// inline call is slightly tricky, have to add our own Env accounting
// emit call is trickier, because we either have to stop or postpone tracing
// use return stack, and count the post-return as it's own trace?
// weirder, but would eventually jive with continuations better?
// eh for now use trace stack in ctx and cont stack out, have them match?
fn trace_call_start(&mut self, arg_len: usize, id: Option<ID>) {
// Needs to take and use parameters for mid-trace
// needs to guard on function called if non-constant
if let Some(id) = id {
let entry = self.func_calls.entry(id).or_insert(0);
println!("tracing call start for {id}, has been called {} times so far", *entry);
*entry += 1;
if *entry > 1 && self.tracing.is_none() && self.traces.get(&id).is_none() {
self.tracing = Some(Trace::new(id));
return; // don't record self, of course
}
}
if let Some(trace) = &mut self.tracing {
let f_params = trace.param_stack.split_off(trace.param_stack.len()-arg_len-1); // include function
if let Some(id) = id {
if trace.id == id {
// check for tail recursion
if trace.param_stack.is_empty() {
trace.ops.push(Op::Loop(f_params));
println!("Ending trace at tail recursive call!");
println!("\t{}", trace);
self.traces.insert(id, self.tracing.take().unwrap());
return;
} else {
// call, and also we have to suspend tracing?
// can treat same as dynamic call if suspend, same thing really
}
}
}
// either inline (prim/closure) or dynamic call
trace.ops.push(Op::Call(f_params));
}
}
fn trace_call_end(&mut self, id: ID) {
// associate with it or something
println!("tracing call end for {id}");
if let Some(trace) = &mut self.tracing {
if trace.id == id {
trace.ops.push(Op::Return);
println!("Ending trace at end of call!");
println!("\t{}", trace);
self.traces.insert(id, self.tracing.take().unwrap());
}
}
}
fn trace_guard<T: Into<Form> + std::fmt::Debug >(&mut self, value: T, other: impl Fn()->(Option<Rc<Form>>,Rc<Cont>)) {
println!("Tracing guard {value:?}");
if let Some(trace) = &mut self.tracing {
trace.ops.push(Op::Guard { const_value: Rc::new(value.into()), side: other() });
}
}
fn trace_debug(&mut self) {
if let Some(trace) = &mut self.tracing {
trace.ops.push(Op::Debug);
}
}
fn trace_define(&mut self, sym: &str) {
if let Some(trace) = &mut self.tracing {
trace.ops.push(Op::Define { sym: sym.to_owned() });
}
}
fn trace_lookup(&mut self, s: &str) {
if let Some(trace) = &mut self.tracing {
trace.ops.push(Op::Lookup { sym: s.to_owned() });
// constant depends on which env
}
}
fn trace_constant(&mut self, c: &Rc<Form>) {
if let Some(trace) = &mut self.tracing {
trace.ops.push(Op::Const { con: Rc::clone(c) });
}
}
fn trace_lambda(&mut self, params: &[String], e: &Rc<RefCell<Env>>, body: &Rc<Form>) {
if let Some(trace) = &mut self.tracing {
// TODO
}
}
}
#[derive(Clone,Debug)]
enum Cont {
MetaRet,
Ret { e: Rc<RefCell<Env>>, id: ID, c: Rc<Cont> },
Eval { c: Rc<Cont> },
Prim { s: &'static str, to_go: Rc<Form>, c: Rc<Cont> },
Call { evaled: Vec<Rc<Form>>, to_go: Rc<Form>, c: Rc<Cont> },
}
pub fn eval(f: Rc<Form>) -> Result<Rc<Form>> {
let mut ctx = Ctx::new();
let mut f = f;
let mut e = Env::root_env();
let mut c = Cont::Eval { c: Rc::new(Cont::MetaRet) };
loop {
match c {
Cont::MetaRet => {
println!("Ctx was {ctx}");
assert!(!ctx.trace_running());
return Ok(f);
}
Cont::Ret { e: ne, id, c: nc } => {
ctx.trace_call_end(id);
e = ne;
c = (*nc).clone();
},
Cont::Prim { s, to_go, c: nc } => {
match s {
"if" => {
let thn = to_go.car()?;
let els = to_go.cdr()?.car()?;
if f.truthy() {
ctx.trace_guard(true, || (Some(Rc::clone(&els)), Rc::new(Cont::Eval { c: Rc::clone(&nc) })));
f = thn;
} else {
ctx.trace_guard(false, ||(Some(Rc::clone(&thn)), Rc::new(Cont::Eval { c: Rc::clone(&nc) })));
f = els;
}
c = Cont::Eval { c: nc };
},
"or" => {
let other = to_go.car()?;
if !f.truthy() {
ctx.trace_guard(false, || (None, nc.clone()));
f = other;
c = Cont::Eval { c: nc };
} else {
ctx.trace_guard(true, || (Some(Rc::clone(&other)), Rc::new(Cont::Eval { c: Rc::clone(&nc) })));
c = (*nc).clone();
}
},
"and" => {
let other = to_go.car()?;
if f.truthy() {
ctx.trace_guard(true, || (None, nc.clone()));
f = other;
c = Cont::Eval { c: nc };
} else {
ctx.trace_guard(false, || (Some(Rc::clone(&other)), Rc::new(Cont::Eval { c: Rc::clone(&nc) })));
c = (*nc).clone();
}
},
"begin" => {
if to_go.is_nil() {
c = (*nc).clone();
} else {
f = to_go.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "begin", to_go: to_go.cdr()?, c: nc }) };
}
},
"debug" => {
println!("Debug: {f}");
ctx.trace_debug();
c = (*nc).clone();
},
"define" => {
let sym = to_go.sym()?.to_string();
ctx.trace_define(&sym);
e.borrow_mut().define(sym, Rc::clone(&f));
c = (*nc).clone();
},
_ => {
panic!("bad prim {s}");
}
}
},
Cont::Call { mut evaled, to_go, c: nc } => {
ctx.trace_call_bit();
evaled.push(f);
if to_go.is_nil() {
// do call
let arg_len = evaled.len() - 1;
let mut evaled_iter = evaled.into_iter();
let comb = evaled_iter.next().unwrap();
match &*comb {
Form::Closure(ps, ie, b, id) => {
if ps.len() != arg_len {
bail!("arguments length doesn't match");
}
let new_env = Env::chain(&ie);
for (name, value) in ps.iter().zip(evaled_iter) {
new_env.borrow_mut().define(name.to_string(), value);
}
ctx.trace_call_start(arg_len, Some(*id));
c = Cont::Eval { c: Rc::new(Cont::Ret { e: Rc::clone(&e), id: *id, c: nc }) };
f = Rc::clone(&b);
e = new_env;
},
Form::Prim(p) => {
ctx.trace_call_start(arg_len, None);
let a = evaled_iter.next().unwrap();
f = match comb.prim().unwrap() {
Prim::Car => a.car()?,
Prim::Cdr => a.cdr()?,
_ => {
let b = evaled_iter.next().unwrap();
match comb.prim().unwrap() {
Prim::Add => Form::new_int(a.int()? + b.int()?),
Prim::Sub => Form::new_int(a.int()? - b.int()?),
Prim::Mul => Form::new_int(a.int()? * b.int()?),
Prim::Div => Form::new_int(a.int()? / b.int()?),
Prim::Mod => Form::new_int(a.int()? % b.int()?),
Prim::Cons => Form::new_pair(a, b),
Prim::Eq => Form::new_bool(a.my_eq(&b)),
_ => unreachable!(),
}
}
};
c = (*nc).clone();
},
_ => {
bail!("tried to call a non-comb {}", comb)
},
}
} else {
f = to_go.car()?;
c = Cont::Eval { c: Rc::new(Cont::Call { evaled, to_go: to_go.cdr()?, c: nc }) };
}
}
Cont::Eval { c: nc } => {
let tmp = f;
match &*tmp {
Form::Symbol(s, _id) => {
ctx.trace_lookup(s);
f = e.borrow().lookup(s)?;
c = (*nc).clone();
},
Form::Pair(car, cdr, _id) => {
match &**car {
Form::Symbol(s, _id) if s == "if" => {
f = cdr.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "if", to_go: cdr.cdr()?, c: nc }) };
}
// and/or has to short-circut, so special form
// just like Scheme (bad ;) )
Form::Symbol(s, _id) if s == "or" => {
f = cdr.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "or", to_go: cdr.cdr()?, c: nc }) };
}
Form::Symbol(s, _id) if s == "and" => {
f = cdr.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "and", to_go: cdr.cdr()?, c: nc }) };
}
Form::Symbol(s, _id) if s == "begin" => {
f = cdr.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "begin", to_go: cdr.cdr()?, c: nc }) };
}
Form::Symbol(s, _id) if s == "debug" => {
f = cdr.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "debug", to_go: cdr.cdr()?, c: nc }) };
}
// This is a fast and loose ~simple lisp~, so just go for it
// and can have convention that this is always top levelish
Form::Symbol(s, _id) if s == "define" => {
// note the swap, evaluating the second not the first (define a value..)
f = cdr.cdr()?.car()?;
c = Cont::Eval { c: Rc::new(Cont::Prim { s: "define", to_go: cdr.car()?, c: nc }) };
}
Form::Symbol(s, _id) if s == "quote" => {
f = cdr.car()?;
ctx.trace_constant(&f);
c = (*nc).clone();
}
// (lambda (a b) body)
Form::Symbol(s, _id) if s == "lambda" => {
let mut params_vec = vec![];
let mut params = cdr.car()?;
while let Ok((ncar, ncdr)) = params.pair() {
params_vec.push(ncar.sym()?.to_string());
params = ncdr;
}
let body = cdr.cdr()?.car()?;
// Later on, the id of the closure should maybe be augmented
// or replaced with the id of the code it was made out of?
ctx.trace_lambda(&params_vec, &e, &body);
f = Form::new_closure(params_vec, Rc::clone(&e), body, &mut ctx);
c = (*nc).clone();
}
_ => {
f = Rc::clone(car);
c = Cont::Eval { c: Rc::new(Cont::Call { evaled: vec![], to_go: Rc::clone(cdr), c: nc }) };
}
}
},
_ => {
// value, no eval
f = tmp;
ctx.trace_constant(&f);
c = (*nc).clone();
}
}
}
}
}
}
// optimized as a function based off side table of id keyed -> opt
// that id might be nice for debugging too
// Symbol ID's could actually be used for environment lookups
// this is just interning
// todo, strings not symbols?
impl From<String> for Form { fn from(item: String) -> Self { Form::Symbol(item, RefCell::new(None)) } }
impl From<&str> for Form { fn from(item: &str) -> Self { Form::Symbol(item.to_owned(), RefCell::new(None)) } }
impl From<i32> for Form { fn from(item: i32) -> Self { Form::Int(item) } }
impl From<bool> for Form { fn from(item: bool) -> Self { Form::Bool(item) } }
impl<A: Into<Form>, B: Into<Form>> From<(A, B)> for Form {
fn from(item: (A, B)) -> Self {
Form::Pair(Rc::new(item.0.into()), Rc::new(item.1.into()), RefCell::new(None))
}
}
impl fmt::Display for Form {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Form::Nil => write!(f, "nil"),
Form::Int(i) => write!(f, "{i}"),
Form::Bool(b) => write!(f, "{b}"),
Form::Symbol(s, _id) => write!(f, "'{s}"),
Form::Pair(car, cdr, _id) => {
write!(f, "({}", car)?;
let mut traverse: Rc<Form> = Rc::clone(cdr);
loop {
match &*traverse {
Form::Pair(ref carp, ref cdrp, ref _id) => {
write!(f, " {}", carp)?;
traverse = Rc::clone(cdrp);
},
Form::Nil => {
write!(f, ")")?;
return Ok(());
},
x => {
write!(f, ". {x})")?;
return Ok(());
},
}
}
},
Form::Closure(params, inner_env, code, id) => {
write!(f, "<closure{} {:?}>", id, params)
}
Form::Prim(p) => {
match p {
Prim::Add => write!(f, "+"),
Prim::Sub => write!(f, "-"),
Prim::Mul => write!(f, "*"),
Prim::Div => write!(f, "/"),
Prim::Mod => write!(f, "%"),
Prim::Cons => write!(f, "cons"),
Prim::Car => write!(f, "car"),
Prim::Cdr => write!(f, "cdr"),
Prim::Eq => write!(f, "="),
}
}
}
}
}

66
slj/src/main.rs Normal file
View File

@@ -0,0 +1,66 @@
#[macro_use] extern crate lalrpop_util;
lalrpop_mod!(pub grammar);
use std::rc::Rc;
use anyhow::Result;
use sl::eval;
fn main() -> Result<()> {
let input = "
(begin
(debug 1)
;(debug (= 1 2))
;(debug (+ 2 3))
;(define a (+ 1 (* 3 4)))
;(define fact (lambda (n) (if (= n 1) 1 (* n (fact (- n 1))))))
;(debug 'gonna_fact_it)
;(debug fact)
;(debug (fact 400))
;(define fact2 (lambda (n a) (if (= n 1) a (fact2 (- n 1) (* n a)))))
;(debug 'gonna_fact2_it)
;(debug fact2)
;(debug (fact2 400 1))
(define faft (lambda (n) (if (= n 1) (debug 1) (+ n (faft (- n 1))))))
(debug 'gonna_faft_it)
(debug faft)
(debug (faft 6))
;(debug (faft 400))
;(define faft2 (lambda (n a) (if (= n 1) a (faft2 (- n 1) (+ n a)))))
;(debug 'gonna_faft2_it)
;(debug faft2)
;(debug (faft2 6 1))
;(debug (faft2 400 1))
;(define fib (lambda (n) (if (or (= n 0) (= n 1)) 1 (+ (fib (- n 1)) (fib (- n 2))))))
;(debug 'gonna_fib_it)
;(debug fib)
;(debug (fib 10))
;(debug a)
;(define b (cons 1 (cons 2 (cons 3 nil))))
;(debug b)
;(debug (car b))
;(debug (cdr b))
(if (= 1 2) (+ 2 3) (* 2 2))
)
";
let parsed_input = Rc::new(grammar::TermParser::new().parse(input)?);
//println!("Hello, world: {parsed_input:?}");
println!("Hello, world: {parsed_input}");
let evaled = eval(Rc::clone(&parsed_input))?;
println!("evaled: {evaled}");
Ok(())
}