Add a very basic lisp1 parser
This commit is contained in:
parent
e527beea5a
commit
47bf80e834
|
@ -1,548 +1,5 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
|
||||
[[package]]
|
||||
name = "ascii-canvas"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29"
|
||||
dependencies = [
|
||||
"term",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f525a586d310c87df72ebcd98009e57f1cc030c8c268305287a476beb653969"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"serde",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6f55673d283313791404be21209bb433f128f7e5c451986df107eb5fdbd68d2"
|
||||
dependencies = [
|
||||
"ascii-canvas",
|
||||
"atty",
|
||||
"bit-set",
|
||||
"diff",
|
||||
"docopt",
|
||||
"ena",
|
||||
"itertools",
|
||||
"lalrpop-util",
|
||||
"petgraph",
|
||||
"regex",
|
||||
"regex-syntax",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sha2",
|
||||
"string_cache",
|
||||
"term",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop-util"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e88f15a7d31dfa8fb607986819039127f0161058a3b248a146142d276cbd28"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[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.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serene"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2940c75beb4e3bf3a494cef919a747a2cb81e52571e212bfbd185074add7208a"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"new_debug_unreachable",
|
||||
"phf_shared",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"dirs",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
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"
|
||||
|
|
|
@ -6,10 +6,4 @@ edition = "2018"
|
|||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
#lalrpop = "0.19.0"
|
||||
lalrpop = { version = "0.19.0", features = ["lexer"] }
|
||||
|
||||
[dependencies]
|
||||
lalrpop-util = "0.19.0"
|
||||
regex = "1"
|
5
build.rs
5
build.rs
|
@ -1,5 +0,0 @@
|
|||
extern crate lalrpop;
|
||||
|
||||
fn main() {
|
||||
lalrpop::process_root().unwrap();
|
||||
}
|
16
src/ast.rs
16
src/ast.rs
|
@ -6,8 +6,8 @@
|
|||
// What about usize and isize ?
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Number {
|
||||
Integer(i32),
|
||||
Float(f32),
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
}
|
||||
|
||||
impl PartialEq for Number {
|
||||
|
@ -17,8 +17,8 @@ impl PartialEq for Number {
|
|||
match comb {
|
||||
(Number::Integer(x), Number::Integer(y)) => *x == *y,
|
||||
(Number::Float(x), Number::Float(y)) => *x == *y,
|
||||
(Number::Integer(x), Number::Float(y)) => *x as f32 == *y,
|
||||
(Number::Float(x), Number::Integer(y)) => *x == *y as f32,
|
||||
(Number::Integer(x), Number::Float(y)) => *x as f64 == *y,
|
||||
(Number::Float(x), Number::Integer(y)) => *x == *y as f64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,4 +34,12 @@ pub enum Expr {
|
|||
Num(Number),
|
||||
Comment,
|
||||
Error(String),
|
||||
Cons(Box<Expr>, Box<Expr>),
|
||||
Nil,
|
||||
NoMatch,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum Error {
|
||||
SyntaxError
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
//! Serene's grammer based on LALRPOP which is a LR(1) parser.
|
||||
use std::str::FromStr;
|
||||
use crate::ast;
|
||||
|
||||
grammar;
|
||||
|
||||
// A collection of Expr objects is simply a sequence of parsed AST objects.
|
||||
pub Exprs: Vec<ast::Expr> = {
|
||||
<v:(<Expr>)*> => v,
|
||||
};
|
||||
|
||||
// Parse an AST expression.
|
||||
Expr: ast::Expr = {
|
||||
// Matches a list
|
||||
"(" <Exprs> ")" => ast::Expr::List(<>),
|
||||
|
||||
// Matches a vector
|
||||
// "[" <Exprs> "]" => Ast::Vector(<>),
|
||||
|
||||
// Match the literal value "nil".
|
||||
// "nil" => Ast::Nil,
|
||||
// Match a Num term.
|
||||
Float => ast::Expr::Num(ast::Number::Float(<>)),
|
||||
Decimal => ast::Expr::Num(ast::Number::Integer(<>)),
|
||||
|
||||
// Matches a string.
|
||||
r#""(?:[^"\\]|\\.)*""# => {
|
||||
let val = <>;
|
||||
ast::Expr::Str(val[1..val.len() - 1].to_owned())
|
||||
},
|
||||
|
||||
// Matches a quoted expr
|
||||
"'" <Expr> => ast::Expr::Quote(Box::new(<>)),
|
||||
|
||||
// Match any token and treat it as an atom.
|
||||
Symbol => ast::Expr::Symbol(<>),
|
||||
! => ast::Expr::Error(format!("{:?}", <>)),
|
||||
};
|
||||
|
||||
// Match any sequence of token characters.
|
||||
Symbol: String = {
|
||||
r#"[A-Za-z_?+*/=<>-]+[0-9A-Za-z_?+*/=<>-]*"# => (<>).to_owned()
|
||||
};
|
||||
|
||||
// Match any valid integer value and treat it as a 32-bit signed integer.
|
||||
Decimal: i32 = {
|
||||
r"[0-9]+" => i32::from_str(<>).unwrap()
|
||||
};
|
||||
|
||||
Float: f32 = {
|
||||
r"[0-9]*\.[0-9]+" => f32::from_str(<>).unwrap()
|
||||
};
|
||||
|
||||
match {
|
||||
r"\s*" => { },
|
||||
r";[^\n\r]*[\n\r]*" => { },
|
||||
_
|
||||
}
|
30
src/main.rs
30
src/main.rs
|
@ -1,32 +1,14 @@
|
|||
#[macro_use]
|
||||
extern crate lalrpop_util;
|
||||
lalrpop_mod!(pub grammer);
|
||||
use std::string::String;
|
||||
|
||||
pub mod ast;
|
||||
pub mod reader;
|
||||
pub mod collections;
|
||||
|
||||
|
||||
use collections::list;
|
||||
|
||||
#[test]
|
||||
fn grammer() {
|
||||
assert!(grammer::ExprsParser::new().parse("a22").is_ok());
|
||||
assert!(grammer::ExprsParser::new().parse("44").is_ok());
|
||||
assert!(grammer::ExprsParser::new().parse("is-ok").is_ok());
|
||||
assert!(grammer::ExprsParser::new().parse("is-ok?").is_ok());
|
||||
assert!(grammer::ExprsParser::new().parse("is-ok+<<>_").is_ok());
|
||||
println!("{:?}", grammer::ExprsParser::new().parse("(as
|
||||
(sad asd) 3i)"));
|
||||
assert!(true);
|
||||
assert!(grammer::ExprsParser::new()
|
||||
.parse("(\"asd\" (symbol (n)))")
|
||||
.is_ok());
|
||||
assert!(grammer::ExprsParser::new()
|
||||
.parse("(\"asd\" (symbol (n 32)))")
|
||||
.is_ok());
|
||||
assert!(grammer::ExprsParser::new().parse("((22)").is_err());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
list::List::h();
|
||||
let input = String::from("(println \">>>>>\" (+ 2 3))");
|
||||
|
||||
println!("{:?}",
|
||||
reader::read_string(&input).unwrap());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
use crate::ast::{Expr, Number};
|
||||
use std::io::{Read, BufReader};
|
||||
|
||||
pub type ReadResult = Result<Expr, String>;
|
||||
|
||||
pub struct ExprReader {
|
||||
read_stack: Vec<char>
|
||||
}
|
||||
|
||||
impl ExprReader {
|
||||
|
||||
fn new() -> ExprReader {
|
||||
ExprReader {
|
||||
read_stack: vec![]
|
||||
}
|
||||
}
|
||||
|
||||
fn get_char<T: Read>(&mut self, reader: &mut BufReader<T>, skip_whitespace: bool) -> Option<char> {
|
||||
loop {
|
||||
match self.read_stack.pop() {
|
||||
Some(c) if !c.is_whitespace() || !skip_whitespace =>
|
||||
{
|
||||
return Some(c)
|
||||
},
|
||||
Some(_) => continue,
|
||||
None => ()
|
||||
};
|
||||
|
||||
// Rust is weird, it doesn't provide a way to read from a buffer char by char.
|
||||
let mut single_char_buff = [0];
|
||||
let bytes_read = reader.read(&mut single_char_buff);
|
||||
match bytes_read {
|
||||
Ok(n) if n > 0 => {},
|
||||
Ok(_) => return None,
|
||||
Err(_) => return None
|
||||
};
|
||||
let ch = single_char_buff[0] as char;
|
||||
|
||||
match ch {
|
||||
c if !c.is_whitespace() || !skip_whitespace => return Some(c),
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn unget_char(&mut self, c: char) {
|
||||
self.read_stack.push(c);
|
||||
}
|
||||
|
||||
// Look ahead. AFAIK Rust doesn't provide any unread functoinality like Java input streams which
|
||||
// sucks.
|
||||
fn peek_char<T: Read>(&mut self, reader: &mut BufReader<T>, skip_whitespace: bool) -> Option<char> {
|
||||
match self.get_char(reader, skip_whitespace) {
|
||||
Some(c) => {
|
||||
self.unget_char(c);
|
||||
Some(c)
|
||||
},
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
fn read_quoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
let rest = self.read_expr(reader)?;
|
||||
Ok(Expr::Cons(Box::new(Expr::Symbol("quote".to_string())), Box::new(rest)))
|
||||
}
|
||||
|
||||
fn read_unquoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
match self.peek_char(reader, true) {
|
||||
Some('@') => {
|
||||
// Move forward in the buffer since we peeked it
|
||||
let _ = self.get_char(reader, true);
|
||||
let rest = self.read_expr(reader)?;
|
||||
Ok(Expr::Cons(Box::new(Expr::Symbol("unquote-splicing".to_string())),
|
||||
Box::new(rest)))
|
||||
},
|
||||
_ => {
|
||||
let rest = self.read_expr(reader)?;
|
||||
Ok(Expr::Cons(Box::new(Expr::Symbol("unquote".to_string())),
|
||||
Box::new(rest)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_quasiquoted_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
let rest = self.read_expr(reader)?;
|
||||
Ok(Expr::Cons(Box::new(Expr::Symbol("quasiquote".to_string())),
|
||||
Box::new(rest)))
|
||||
}
|
||||
|
||||
// TODO: We might want to replace Cons with an actual List struct
|
||||
fn read_list<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
let first = match self.read_expr(reader) {
|
||||
Ok(value) => value,
|
||||
Err(e) => match self.get_char(reader, true) {
|
||||
// is it an empty list ?
|
||||
// TODO: we might want to return an actual empty list here
|
||||
Some(')') => return Ok(Expr::Nil),
|
||||
_ => return Err(e)
|
||||
}
|
||||
};
|
||||
let rest = match self.get_char(reader, true) {
|
||||
Some(e) => {
|
||||
self.unget_char(e);
|
||||
self.read_list(reader)?
|
||||
},
|
||||
None => return Err("Unexpected EOF, expected . or symbol".to_string())
|
||||
};
|
||||
|
||||
Ok(Expr::Cons(Box::new(first), Box::new(rest)))
|
||||
}
|
||||
|
||||
fn is_valid_for_identifier(&self, c: char) -> bool {
|
||||
match c {
|
||||
'!' | '$' | '%' | '&' | '*' | '+' | '-' | '.' | '~' |
|
||||
'/' | ':' | '<' | '=' | '>' | '?' | '@' | '^' | '_' |
|
||||
'a'..='z' | 'A'..='Z' | '0'..='9' => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn _read_symbol<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
let mut symbol = match self.peek_char(reader, false) {
|
||||
Some(e) if self.is_valid_for_identifier(e) => {
|
||||
// Read into string
|
||||
let ch = self.get_char(reader, false).unwrap();
|
||||
let mut s = String::new();
|
||||
s.push(ch);
|
||||
s
|
||||
},
|
||||
Some(e) => {
|
||||
return Err(format!("Unexpected character: got {}, expected a symbol", e))
|
||||
},
|
||||
None => return Err("Unexpected EOF".to_string())
|
||||
};
|
||||
|
||||
loop {
|
||||
match self.get_char(reader, false) {
|
||||
Some(v) if self.is_valid_for_identifier(v) => symbol.push(v),
|
||||
Some(v) => {
|
||||
self.unget_char(v);
|
||||
break;
|
||||
},
|
||||
None => break
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Expr::Symbol(symbol))
|
||||
}
|
||||
|
||||
fn read_escape_char<T: Read>(&mut self, reader: &mut BufReader<T>) -> Option<char> {
|
||||
match self.get_char(reader, false) {
|
||||
Some(e) => match e {
|
||||
'\"' => Some('\"'),
|
||||
'\'' => Some('\''),
|
||||
'\\' => Some('\\'),
|
||||
'n' => Some('\n'),
|
||||
'r' => Some('\r'),
|
||||
't' => Some('\t'),
|
||||
_ => None
|
||||
},
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
fn read_string<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
// Skip the " char
|
||||
let _ = self.get_char(reader, false);
|
||||
|
||||
let mut string = "".to_string();
|
||||
loop {
|
||||
match self.get_char(reader, false) {
|
||||
Some(e) => match e {
|
||||
'\"' => break,
|
||||
'\\' => match self.read_escape_char(reader) {
|
||||
Some(v) => string.push(v),
|
||||
None => return Err(format!("Unexpected char to escape, got {}", e))
|
||||
},
|
||||
//'\n' => return Err("Unescaped newlines are not allowed in string literals".to_string()),
|
||||
_ => string.push(e)
|
||||
},
|
||||
None => return Err("Unexpected EOF while scanning a string".to_string())
|
||||
}
|
||||
}
|
||||
Ok(Expr::Str(string))
|
||||
}
|
||||
|
||||
fn read_number<T: Read>(&mut self, reader: &mut BufReader<T>, neg: bool) -> ReadResult {
|
||||
let mut is_double = false;
|
||||
let mut string = "".to_string();
|
||||
loop {
|
||||
match self.get_char(reader, false) {
|
||||
Some(e) if e == '.' && is_double => return Err("A double with more that one '.' ???".to_string()),
|
||||
Some(e) if e == '.' => {
|
||||
is_double = true;
|
||||
string.push(e);
|
||||
}
|
||||
Some(e) if e.is_digit(10) => string.push(e),
|
||||
Some(e) => {
|
||||
self.unget_char(e);
|
||||
break;
|
||||
}
|
||||
None => break
|
||||
}
|
||||
}
|
||||
if is_double {
|
||||
Ok(Expr::Num(Number::Float(string.parse::<f64>().unwrap())))
|
||||
} else {
|
||||
Ok(Expr::Num(Number::Integer(string.parse::<i64>().unwrap())))
|
||||
}
|
||||
}
|
||||
|
||||
fn read_symbol<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
match self.peek_char(reader, true) {
|
||||
Some(c) => match c {
|
||||
'\"' => self.read_string(reader),
|
||||
c if c.is_digit(10) => self.read_number(reader, false),
|
||||
|
||||
// ':' => self.read_keyword(reader),
|
||||
// '-' => {
|
||||
// Neg number
|
||||
// }
|
||||
_ => self._read_symbol(reader)
|
||||
},
|
||||
None => Err("Unexpected EOF while scanning atom".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_expr<T: Read>(&mut self, reader: &mut BufReader<T>) -> ReadResult {
|
||||
match self.get_char(reader, true) {
|
||||
Some(c) => {
|
||||
match c {
|
||||
'\'' => self.read_quoted_expr(reader),
|
||||
'~' => self.read_unquoted_expr(reader),
|
||||
'`' => self.read_quasiquoted_expr(reader),
|
||||
'(' => self.read_list(reader),
|
||||
//'[' => self.read_vector(reader),
|
||||
//'{' => self.read_map(reader),
|
||||
_ => {
|
||||
self.unget_char(c);
|
||||
self.read_symbol(reader)
|
||||
}
|
||||
}
|
||||
},
|
||||
None => Ok(Expr::NoMatch)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_from_buffer<T: Read>(&mut self, reader: &mut BufReader<T>) -> Result<Vec<Expr>, String> {
|
||||
let mut ast = vec![];
|
||||
loop {
|
||||
match self.read_expr(reader) {
|
||||
Ok(Expr::NoMatch) => break,
|
||||
Err(v) => return Err(v),
|
||||
Ok(v) => ast.push(v)
|
||||
}
|
||||
}
|
||||
Ok(ast)
|
||||
}
|
||||
|
||||
pub fn read(&mut self, string: &str) -> Result<Vec<Expr>, String> {
|
||||
let reader = BufReader::new(string.as_bytes());
|
||||
let mut buf_reader = BufReader::new(reader);
|
||||
self.read_from_buffer(&mut buf_reader)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn read_string(input: &str) -> Result<Vec<Expr>, String> {
|
||||
let mut reader = ExprReader::new();
|
||||
reader.read(input)
|
||||
}
|
Loading…
Reference in New Issue