A => .cargo/config.toml +17 -0
@@ 0,0 1,17 @@
+[profile.dev]
+lto = "off"
+
+[profile.release]
+codegen-units = 1
+lto = "fat"
+
+[profile.small]
+inherits = "release"
+opt-level = "z"
+strip = "symbols"
+
+[build]
+rustflags = ["-C", "target-cpu=native"]
+
+[target.x86_64-unknown-linux-gnu]
+rustflags = ["-C", "link-arg=-fuse-ld=mold"]
A => .editorconfig +12 -0
@@ 0,0 1,12 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
A => .envrc +1 -0
A => .gitignore +14 -0
@@ 0,0 1,14 @@
+# Build artifacts
+node_modules/
+result
+target/
+
+# Generated files
+**/*.rs.bk
+
+# Operating System specific files
+.DS_Store
+Thumbs.db
+
+# https://github.com/nix-community/nix-direnv
+.direnv
A => .hgignore +11 -0
@@ 0,0 1,11 @@
+# Build artifacts
+node_modules/
+result
+target/
+
+# Operating System specific files
+.DS_Store
+Thumbs.db
+
+# https://github.com/nix-community/nix-direnv
+.direnv
A => Cargo.lock +1744 -0
@@ 0,0 1,1744 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anstream"
+version = "0.6.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+dependencies = [
+ "anstyle",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "backtrace-ext"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
+dependencies = [
+ "backtrace",
+]
+
+[[package]]
+name = "bee-lang"
+version = "0.1.0"
+dependencies = [
+ "clap",
+ "clap_mangen",
+ "deno_core",
+ "directories",
+ "env_logger",
+ "exitcode",
+ "human-panic",
+ "lazy_static",
+ "log",
+ "miette",
+ "owo-colors 4.0.0",
+ "pathdiff",
+ "rayon",
+ "regex",
+ "rquickjs",
+ "thiserror",
+ "tree-sitter",
+ "tree-sitter-bee-lang",
+ "walkdir",
+]
+
+[[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.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+
+[[package]]
+name = "bytes"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+
+[[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "4.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
+
+[[package]]
+name = "clap_mangen"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43144ab702c764b0a3ecda5ecd2aba2e6874d8de4b9f56930bbb1e88fcecd84a"
+dependencies = [
+ "clap",
+ "roff",
+]
+
+[[package]]
+name = "colorchoice"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "cooked-waker"
+version = "5.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147be55d677052dabc6b22252d5dd0fd4c29c8c27aa4f2fbef0f94aa003b406f"
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
+
+[[package]]
+name = "data-encoding"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
+
+[[package]]
+name = "debugid"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
+dependencies = [
+ "serde",
+ "uuid",
+]
+
+[[package]]
+name = "deno_core"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c18f86123119dffd1f2f016ff5b858b878971c042a18493794b219a33a69dda"
+dependencies = [
+ "anyhow",
+ "bit-set",
+ "bit-vec",
+ "bytes",
+ "cooked-waker",
+ "deno_ops",
+ "deno_unsync",
+ "futures",
+ "libc",
+ "log",
+ "memoffset",
+ "parking_lot",
+ "pin-project",
+ "serde",
+ "serde_json",
+ "serde_v8",
+ "smallvec",
+ "sourcemap",
+ "static_assertions",
+ "tokio",
+ "url",
+ "v8",
+]
+
+[[package]]
+name = "deno_ops"
+version = "0.120.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed8f888f466c80fdec64d0ec2fb12b0f56b0f1ae4815bb20a1895cc7097fb775"
+dependencies = [
+ "proc-macro-rules",
+ "proc-macro2",
+ "quote",
+ "strum",
+ "strum_macros",
+ "syn 2.0.48",
+ "thiserror",
+]
+
+[[package]]
+name = "deno_unsync"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30dff7e03584dbae188dae96a0f1876740054809b2ad0cf7c9fc5d361f20e739"
+dependencies = [
+ "tokio",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version 0.4.0",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "directories"
+version = "5.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+dependencies = [
+ "libc",
+ "option-ext",
+ "redox_users",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "either"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+
+[[package]]
+name = "env_logger"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
+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.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "exitcode"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "fslock"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57eafdd0c16f57161105ae1b98a1238f97645f2f588438b2949c99a2af9616bf"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "futures"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+
+[[package]]
+name = "futures-task"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+[[package]]
+name = "futures-util"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f"
+
+[[package]]
+name = "home"
+version = "0.5.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "human-panic"
+version = "1.2.3"
+source = "git+https://github.com/yvan-sraka/human-panic.git#07cc1dff71837b8530d1c3606411f21cb2b66c85"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "backtrace",
+ "os_info",
+ "serde",
+ "serde_derive",
+ "toml",
+ "uuid",
+]
+
+[[package]]
+name = "idna"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "if_chain"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
+
+[[package]]
+name = "indexmap"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
+dependencies = [
+ "hermit-abi",
+ "rustix",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "is_ci"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
+
+[[package]]
+name = "itoa"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+
+[[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.152"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
+
+[[package]]
+name = "libredox"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
+dependencies = [
+ "bitflags 2.4.2",
+ "libc",
+ "redox_syscall",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
+
+[[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 = "memchr"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
+
+[[package]]
+name = "memoffset"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "miette"
+version = "5.10.0"
+source = "git+https://github.com/yvan-sraka/miette.git#1ab33608b2d0c18b0307fbf2035212acde003bd1"
+dependencies = [
+ "backtrace",
+ "backtrace-ext",
+ "is-terminal",
+ "miette-derive",
+ "once_cell",
+ "owo-colors 3.5.0",
+ "supports-color",
+ "supports-hyperlinks",
+ "supports-unicode",
+ "terminal_size",
+ "textwrap",
+ "thiserror",
+ "unicode-width",
+]
+
+[[package]]
+name = "miette-derive"
+version = "5.10.0"
+source = "git+https://github.com/yvan-sraka/miette.git#1ab33608b2d0c18b0307fbf2035212acde003bd1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+ "rand",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.32.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "option-ext"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+
+[[package]]
+name = "os_info"
+version = "3.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e"
+dependencies = [
+ "log",
+ "serde",
+ "winapi",
+]
+
+[[package]]
+name = "owo-colors"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
+
+[[package]]
+name = "owo-colors"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f"
+dependencies = [
+ "supports-color",
+]
+
+[[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 0.48.5",
+]
+
+[[package]]
+name = "pathdiff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "pin-project"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "proc-macro-rules"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07c277e4e643ef00c1233393c673f655e3672cf7eb3ba08a00bdd0ea59139b5f"
+dependencies = [
+ "proc-macro-rules-macros",
+ "proc-macro2",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "proc-macro-rules-macros"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "207fffb0fe655d1d47f6af98cc2793405e85929bdbc420d685554ff07be27ac7"
+dependencies = [
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
+[[package]]
+name = "rayon"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[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 = "regex"
+version = "1.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+
+[[package]]
+name = "roff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
+
+[[package]]
+name = "rquickjs"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "511ee02660e19cf451ebcbda6151a4023044293066e9ccd2b0498047203f6ab1"
+dependencies = [
+ "rquickjs-core",
+]
+
+[[package]]
+name = "rquickjs-core"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c10ce0bc11e249e738aadb8119e9a7619125cb866208236d88d2ee3dcdb7a67d"
+dependencies = [
+ "rquickjs-sys",
+]
+
+[[package]]
+name = "rquickjs-sys"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86030d52fc20e68115f93738c2cb960d6f900f64d99e1013ea0e170381eb0a72"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+dependencies = [
+ "semver 0.9.0",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver 1.0.21",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
+dependencies = [
+ "bitflags 2.4.2",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+
+[[package]]
+name = "ryu"
+version = "1.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "serde"
+version = "1.0.196"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.196"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.113"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
+dependencies = [
+ "indexmap",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_v8"
+version = "0.153.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a53364678111a47806ca93b8485acd66a4a2d37da733564dcc3e76a91531ba6"
+dependencies = [
+ "bytes",
+ "derive_more",
+ "num-bigint",
+ "serde",
+ "smallvec",
+ "thiserror",
+ "v8",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+
+[[package]]
+name = "smawk"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
+
+[[package]]
+name = "socket2"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
+dependencies = [
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "sourcemap"
+version = "7.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10da010a590ed2fa9ca8467b00ce7e9c5a8017742c0c09c45450efc172208c4b"
+dependencies = [
+ "data-encoding",
+ "debugid",
+ "if_chain",
+ "rustc_version 0.2.3",
+ "serde",
+ "serde_json",
+ "unicode-id",
+ "url",
+]
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "strum"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
+dependencies = [
+ "strum_macros",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.25.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "supports-color"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89"
+dependencies = [
+ "is-terminal",
+ "is_ci",
+]
+
+[[package]]
+name = "supports-hyperlinks"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d"
+dependencies = [
+ "is-terminal",
+]
+
+[[package]]
+name = "supports-unicode"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f850c19edd184a205e883199a261ed44471c81e39bd95b1357f5febbef00e77a"
+dependencies = [
+ "is-terminal",
+]
+
+[[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]]
+name = "syn"
+version = "2.0.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "terminal_size"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
+dependencies = [
+ "smawk",
+ "unicode-linebreak",
+ "unicode-width",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.35.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "libc",
+ "mio",
+ "num_cpus",
+ "parking_lot",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.48",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+]
+
+[[package]]
+name = "tree-sitter"
+version = "0.20.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e747b1f9b7b931ed39a548c1fae149101497de3c1fc8d9e18c62c1a66c683d3d"
+dependencies = [
+ "cc",
+ "regex",
+]
+
+[[package]]
+name = "tree-sitter-bee-lang"
+version = "0.1.0"
+dependencies = [
+ "cc",
+ "tree-sitter",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+
+[[package]]
+name = "unicode-id"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-linebreak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+
+[[package]]
+name = "url"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
+[[package]]
+name = "uuid"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "v8"
+version = "0.82.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f53dfb242f4c0c39ed3fc7064378a342e57b5c9bd774636ad34ffe405b808121"
+dependencies = [
+ "bitflags 1.3.2",
+ "fslock",
+ "once_cell",
+ "which",
+]
+
+[[package]]
+name = "walkdir"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "which"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
+dependencies = [
+ "either",
+ "home",
+ "once_cell",
+ "rustix",
+]
+
+[[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-util"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+dependencies = [
+ "winapi",
+]
+
+[[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 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
+]
+
+[[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_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
+[[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_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
+[[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_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
+[[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_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
A => Cargo.toml +43 -0
@@ 0,0 1,43 @@
+[package]
+name = "bee-lang"
+version = "0.1.0"
+edition = "2021"
+authors = ["Yvan Sraka <yvan@sraka.xyz>"]
+license = "GPLv2"
+
+[lib]
+name = "bee"
+crate-type = ["cdylib", "rlib"]
+
+[[bin]]
+name = "bee"
+
+[dependencies]
+clap = { version = "4.4", features = ["derive"] }
+deno_core = { version = "0.244", optional = true }
+directories = "5.0"
+env_logger = { default-features = false, version = "0.10" }
+exitcode = "1.1"
+human-panic = { git = "https://github.com/yvan-sraka/human-panic.git", version = "1.2" }
+lazy_static = "1.4"
+log = "0.4"
+miette = { git = "https://github.com/yvan-sraka/miette.git", version = "5.10", features = ["fancy"] }
+owo-colors = { version = "4.0", features = ["supports-colors"] }
+pathdiff = "0.2"
+rayon = { version = "1.8", optional = true }
+regex = { default-features = false, version = "1.10" }
+rquickjs = { version = "0.4", optional = true , default-features = false }
+thiserror = "1.0"
+tree-sitter = "0.20"
+tree-sitter-bee-lang = { path = "./tree-sitter-bee-lang", version = "0.1" }
+walkdir = "2.4"
+
+[features]
+default = ["quickjs", "rayon"]
+deno = ["dep:deno_core"]
+quickjs = ["dep:rquickjs"]
+rayon = ["dep:rayon"]
+
+[build-dependencies]
+clap = { version = "4.4", features = ["derive"] }
+clap_mangen = "0.2"
A => LICENSE +661 -0
@@ 0,0 1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<https://www.gnu.org/licenses/>.
A => README.md +61 -0
@@ 0,0 1,61 @@
+# Bee programming language
+
+A small language that is **easy to learn** and that helps you wrote **bug-free** programs.
+
+The project was introduced at FOSDEM 2024, you can find the slides [here](https://topaz-candle-mimosa.glitch.me).
+
+```bee
+// A quick taste of the Bee syntax:
+{ Flower = type ("🌸" | "🌺" | "🌼")
+ { fmt = args => "${args.animal} is ${args.mood}!"
+ return x => fmt { animal = "🐝"; mood = if Flower x "happy" else "sad" }
+ } (read "/dev/stdin") |> print
+}
+```
+
+Check out the [`examples`](./examples) folder, for more code snippets.
+
+Bee currently compile to JavaScript but aims to suitable for system programming!
+
+One core design idea to keep the language small is to define most of construct in the [standard library](./src/prelude.bee).
+
+<!--
+- Read the **User Guide**, if you want to learn the Bee syntax and run your first program.
+- Follow the **Contributors Book** a.k.a. "Le livre des fleurs 🌸 🌺 🌼", if you want to get an overview of how Bee architectured by getting a tour of the project codebase.
+- Head to the **Research Blog**, if you want insights on motivations behind the design decisions of the language.
+-->
+
+# Usage
+
+Get a Rust toolchain working on your computer, and then `cargo install --git https://git.sr.ht/~yvan-sraka/bee-lang` to build from source.
+
+Check out the [Syntax Highlighting Guide](./tree-sitter-bee-lang/README.md) to set-up your code editor. You can also find an [example](examples/webpack-demo) on how to set-up Webpack to work with Bee.
+
+# Roadmap
+
+## What Has Been Implemented...
+
+- Funny **Bugs**! 🐛
+- **Syntax** `grammar.js` with TreeSitter;
+- **Semantics** (destructuring, spread operator, implicit function arguments, operator overloading, etc.);
+- **Prelude** (minimal standard library);
+- **CLI** (that works without `node` in your `PATH`);
+- **Build targets** (e.g., `@debug`, `@release` or user-defined);
+- **Build cache** (file-based);
+- **Basic editor support** (syntax highlighting);
+
+## What's Left to Do...
+
+- **Pattern matching** (in lambda definition, let-bindings and branches of a `match` keyword);
+- **Constrained mutability** (e.g. needed for `while` loops);
+- **Subtyping** (keeping track of the partial order of Types declared within a scope).
+- A Language Server Protocol (**LSP**) and Debug Adapter Protocol (**DAP**);
+- A **native backend** (C, WASM or LLVM);
+- An **incremental typing** algorithm;
+- A language **package manager**.
+
+# Mailing-lists
+
+- [announce@bee-lang.org](https://groups.google.com/g/bee-lang-announce): Low-volume mailing list for announcements related to the https://bee-lang.org project.
+- [devel@bee-lang.org](https://groups.google.com/g/bee-lang-devel): Mailing list for development discussion and patches related to the https://bee-lang.org project. For help sending patches to this list, please consult https://git-send-email.io.
+- [discuss@bee-lang.org](https://groups.google.com/g/bee-lang-discuss): Mailing list for end-user discussion and questions related to the https://bee-lang.org project.
A => build.rs +20 -0
@@ 0,0 1,20 @@
+use clap::CommandFactory;
+
+#[path = "src/cli.rs"]
+mod cli;
+
+fn main() -> std::io::Result<()> {
+ let out_dir =
+ std::path::PathBuf::from(std::env::var_os("OUT_DIR").ok_or(std::io::ErrorKind::NotFound)?);
+ let cmd = cli::Cli::command();
+
+ let man = clap_mangen::Man::new(cmd);
+ let mut buffer: Vec<u8> = Default::default();
+ man.render(&mut buffer)?;
+
+ // FIXME: use `man` crate for further customization :)
+
+ std::fs::write(out_dir.join("bee.1"), buffer)?;
+
+ Ok(())
+}
A => default.nix +47 -0
@@ 0,0 1,47 @@
+{ pkgs ? import <nixpkgs> { }, lib ? pkgs.lib, rustPlatform ? pkgs.rustPlatform
+, fetchurl ? pkgs.fetchurl, system ? builtins.currentSystem }:
+
+rustPlatform.buildRustPackage rec {
+ pname = "bee-lang";
+ version = "0.1.0";
+
+ src = fetchurl {
+ url = "https://git.sr.ht/~yvan-sraka/bee-lang/archive/v${version}.tar.gz";
+ sha256 = lib.fakeSha256; # You have to put here the Nix "expected" hash :)
+ };
+
+ cargoLock = {
+ lockFile = ./Cargo.lock;
+ outputHashes = {
+ "human-panic-1.2.3" =
+ "sha256-rtRyNQUATcaGJC5RZk5K0ClY0c1aTxccYXCi16h02oY=";
+ "miette-5.10.0" = "sha256-ru/cKlegkeqq1y/w1O3k50jYOtvwsXod7VCK65/ToP4=";
+ };
+ };
+
+ nativeBuildInputs = with pkgs;
+ [ nodejs tree-sitter ]
+ ++ (if system == "x86_64-linux" then [ mold ] else [ ]);
+
+ buildPhase = ''
+ runHook preBuild
+ pushd tree-sitter
+ tree-sitter generate
+ popd
+ cargo build --release
+ runHook postBuild
+ '';
+
+ installPhase = ''
+ runHook preInstall
+ install -D target/release/bee -t $out/bin
+ runHook postInstall
+ '';
+
+ meta = with lib; {
+ description = "The Bee programming language compiler";
+ homepage = "https://bee-lang.org";
+ license = licenses.gpl2;
+ maintainers = with maintainers; [ maintainers.yvan-sraka ];
+ };
+}
A => examples/arrays.bee +5 -0
@@ 0,0 1,5 @@
+{
+ x = [ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ]
+ // This will be check (and error) at build-time:
+ print x.42
+}
A => examples/assert.bee +7 -0
@@ 0,0 1,7 @@
+{
+ x = _ => assert false
+ // This will error at build-time and display a debug "stack-trace"
+ x {}
+ // One other way to error is to directly:
+ panic "Custom error message :$"
+}
A => +3 -0
@@ 0,0 1,3 @@
+/* Block comments could be /* nested */ */
+// Inline comments disable any */ or /* later in the same line!
+"//, /* and /* in strings are (indeed) ignored!"
A => examples/custom_target.bee +3 -0
@@ 0,0 1,3 @@
+// This will print a different value if `--targets release` is passed as CLI
+// argument to `bee build`:
+print (if @debug "debug" else "release")
A => examples/greetings.bee +5 -0
@@ 0,0 1,5 @@
+// A file/module could contain any arbitrary expression, like a function:
+name => print "Hello, ${name}!"
+// Strings support interpolation of simple identifiers!
+
+// FIXME: demonstrate the `import` keyword!
A => examples/if_then_else.bee +7 -0
@@ 0,0 1,7 @@
+{
+ // if statement could be assigned and chained:
+ x = if false 1 else if true 2 else 3
+ // the else clause is always required!
+}
+
+// FIXME: better explain boolean and comparison operator
A => examples/infinite_recursion.bee +2 -0
@@ 0,0 1,2 @@
+// FIXME: This currently fail with an unprecise error ...
+{ x = _ => { print ":/"; x {} }; x {} }
A => examples/inherit.bee +6 -0
@@ 0,0 1,6 @@
+{
+ a = 13
+ b = 12
+ // This is just syntaxic sugar for: { a = a; b = b }
+ return { a; b }
+}
A => examples/lexical_scoping.bee +8 -0
@@ 0,0 1,8 @@
+{
+ // This fail because x isn't accessible in the definition site of f
+ f = _ => print x
+ {
+ x = 42
+ f {}
+ }
+}
A => examples/maths.bee +4 -0
@@ 0,0 1,4 @@
+// Bee is a calculator. But you should not mix BigInt and Float!
+(3.14 * 2.0) + 1.0
+
+// FIXME: better demonstrate build-time checks, like the "divide by 0" guard
A => examples/op_overloading.bee +13 -0
@@ 0,0 1,13 @@
+{
+ a = {
+ ops = {
+ // Let's redefine `+`, but for complex numbers:
+ add = x => y => { r = x.r + y.r ; i = x.i + y.i }
+ }
+ x = { r = 1.0; i = 0.0 } + { r = 0.0 ; i = 1.0 }
+ // This will fail since `-` is now undefined in this scope
+ // y = { r = 1.0; i = 0.0 } - { r = 0.0 ; i = 1.0 }
+ }
+ // But here, everything is back to normal!
+ b = 3.0 - 2.0
+}
A => examples/parsing_errors.bee +6 -0
@@ 0,0 1,6 @@
+// We try to display syntax hints to user when parsing error happens since
+// tree-sitter messages are often a bit helpless ...
+{
+ x = return 42
+ import hello
+}
A => examples/pipes.bee +6 -0
@@ 0,0 1,6 @@
+{
+ inc = x => x + 1
+ triple = x => x * 3
+ // Tho following line is equivalent to: triple (inc 3)
+ res = 3 |> (inc |> triple)
+}
A => examples/ranges.bee +1 -0
@@ 0,0 1,1 @@
+2..5 // is equivalent to [2, 3, 4]
A => examples/self.bee +10 -0
@@ 0,0 1,10 @@
+// `self` is a pointer to the closest block in which a function is defined ...
+// ... it's a weird semantic and this will likely change!
+
+{
+ math = {
+ odd = x => if (x == 1) true else if (x == 0) false else (self.even (x - 1))
+ even = x => if (x == 0) true else if (x == 1) false else (self.odd (x - 1))
+ }
+ print (math.even 42)
+}
A => examples/spread.bee +4 -0
@@ 0,0 1,4 @@
+{
+ x = {a = 2; b = 3}
+ y = {a = 1; ...x; b = 4} // y now equals {a = 2; b = 4}
+}
A => examples/too_many_args.bee +5 -0
@@ 0,0 1,5 @@
+{
+ x = _ => { print ":(" }
+ // This will be check (and error) at build-time:
+ x 1 2
+}
A => examples/webpack-demo/.gitignore +2 -0
@@ 0,0 1,2 @@
+node_modules
+dist
A => examples/webpack-demo/package-lock.json +1372 -0
@@ 0,0 1,1372 @@
+{
+ "name": "webpack-demo",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "webpack-demo",
+ "version": "0.1.0",
+ "license": "GPLv2",
+ "dependencies": {
+ "bee-webpack-loader": "file:../../webpack-loader"
+ },
+ "devDependencies": {
+ "webpack": "^5.89.0",
+ "webpack-cli": "^5.1.4"
+ }
+ },
+ "../../webpack-loader": {
+ "version": "0.1.0",
+ "license": "GPLv2"
+ },
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.22",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
+ "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "8.56.2",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz",
+ "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "20.11.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.10.tgz",
+ "integrity": "sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "dev": true,
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "dev": true
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "dev": true,
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.6",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webpack-cli/configtest": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
+ "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/info": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/serve": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x",
+ "webpack-cli": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.11.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+ "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-assertions": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/bee-webpack-loader": {
+ "resolved": "../../webpack-loader",
+ "link": true
+ },
+ "node_modules/browserslist": {
+ "version": "4.22.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz",
+ "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001580",
+ "electron-to-chromium": "^1.4.648",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001581",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz",
+ "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.650",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.650.tgz",
+ "integrity": "sha512-sYSQhJCJa4aGA1wYol5cMQgekDBlbVfTRavlGZVr3WZpDdOPcp6a6xUnFfrt8TqZhsBYYbDxJZCjGfHuGupCRQ==",
+ "dev": true
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
+ "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
+ "dev": true,
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
+ "dev": true
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
+ "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+ "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.20.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.8",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.27.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
+ "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.10",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+ "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.20",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.26.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+ "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "dev": true,
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack": {
+ "version": "5.90.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.0.tgz",
+ "integrity": "sha512-bdmyXRCXeeNIePv6R6tGPyy20aUobw4Zy8r0LUS2EWO+U+Ke/gYDgsCh7bl5rB6jPpr4r0SZa6dPxBxLooDT3w==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.3",
+ "@types/estree": "^1.0.5",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
+ "acorn": "^8.7.1",
+ "acorn-import-assertions": "^1.9.0",
+ "browserslist": "^4.21.10",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.9",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.2.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.10",
+ "watchpack": "^2.4.0",
+ "webpack-sources": "^3.2.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
+ "dev": true,
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
+ "colorette": "^2.0.14",
+ "commander": "^10.0.1",
+ "cross-spawn": "^7.0.3",
+ "envinfo": "^7.7.3",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^3.1.1",
+ "rechoir": "^0.8.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/webpack-merge": {
+ "version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+ "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+ "dev": true,
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "flat": "^5.0.2",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wildcard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+ "dev": true
+ }
+ }
+}
A => examples/webpack-demo/package.json +21 -0
@@ 0,0 1,21 @@
+{
+ "name": "webpack-demo",
+ "version": "0.1.0",
+ "description": "Demo of bee-webpack-loader",
+ "private": true,
+ "source": "src/index.js",
+ "main": "dist/main.js",
+ "scripts": {
+ "build": "webpack",
+ "start": "node dist/main.js"
+ },
+ "author": "Yvan Sraka <yvan@sraka.xyz>",
+ "license": "GPLv2",
+ "devDependencies": {
+ "webpack": "^5.89.0",
+ "webpack-cli": "^5.1.4"
+ },
+ "dependencies": {
+ "bee-webpack-loader": "file:../../webpack-loader"
+ }
+}
A => examples/webpack-demo/src/greetings.bee +1 -0
@@ 0,0 1,1 @@
+name => print "Hello, ${name}!"
A => examples/webpack-demo/src/index.js +3 -0
@@ 0,0 1,3 @@
+import greetings from './greetings.bee'
+
+greetings("World")
A => examples/webpack-demo/webpack.config.js +11 -0
@@ 0,0 1,11 @@
+module.exports = {
+ mode: 'development',
+ module: {
+ rules: [
+ {
+ test: /\.bee$/,
+ use: 'bee-webpack-loader'
+ }
+ ]
+ }
+};
A => examples/weird_expr.bee +6 -0
@@ 0,0 1,6 @@
+// This expression is evaluated to { a = 42; b = 42 } }
+{ a = 42; b = { return a } }
+// The return keyword replace the value of the Object in which it's called by
+// its argument!
+
+// FIXME: better explain do-block semantics ...
A => experimental/bootstrap.js +172 -0
@@ 0,0 1,172 @@
+const sexpr = s =>
+ { let i = 0; const rec = () =>
+ { if (/\s/.test(s[i])) { ++i }
+ else if (s[i] === '(') { ++i; elements.push(rec()) }
+ else if (s[i] === ')') { ++i; return elements }
+ else if (s[i]== '"')
+ { let start = ++i; while (i < s.length && s[i] !== '"') { ++i }
+ elements.push(s.slice(start - 1, ++i)) }
+ else
+ { let start = i; while (i < s.length && !/\s|\(|\)/.test(s[i])) { ++i }
+ elements.push(s.slice(start, i)) }
+ return elements }
+ return rec() }
+
+const err = msg => { throw new Error(`\x1b[31m\x1b[1m${msg}\x1b[0m`) }
+const assert = x => { if (!x) { err('Assertion failed') } }
+
+const parse = s =>
+ { const sexpr = s =>
+ { let i = 0
+ const rec = () =>
+ { let elements = []
+ while (i < s.length)
+ { if (/\s/.test(s[i])) ++i
+ else if (s[i] === '(') { ++i; elements.push(rec()) }
+ else if (s[i] === ')') { ++i; return elements }
+ else if (s[i] == '"')
+ { let start = ++i
+ while (i < s.length && s[i] !== '"') ++i
+ elements.push(s.slice(start - 1, ++i)) }
+ else
+ { let start = i
+ while (i < s.length && !/\s|\(|\)/.test(s[i])) ++i
+ elements.push(s.slice(start, i)) } }
+ return elements }
+ return rec() }
+ // This parser always return an Array, which can be seen as like the whole
+ // expression is always implicitly wraped into parenthesis:
+ // assert(sexpr(``), []);
+ // This is an S-Expression parser, spaces are ignored:
+ // assert(sexpr(` (A ( B C ) D `), [ [ 'A', [ 'B', 'C' ] ], 'D' ]);
+ // Strings are written within " and could contains parenthesis:
+ // assert(sexpr(`(print "Hello :-)")`), [ [ 'print', '"Hello :-)"' ] ]);
+ // The parser will implicitly add missing closing parenthesis at the end of
+ // the input, and will ignore every extra closing parenthesis:
+ // assert(sexpr(`(((X`), [ [ [ [ 'X' ] ] ] ]);
+ // assert(sexpr(`X)))`), [ 'X' ]);
+ // The core design goal of this parser is to never fail, but here (for debug
+ // purposes) we provide a stricter version of it that only accept a subset of
+ // "valid" programs:
+ const x = sexpr(s)
+ return x.length == 1 ? x[0] : err("Malformed program") }
+
+const get = (obj, path) =>
+ { const keys = path.split('.')
+ let current = obj
+ for (const key of keys)
+ { if (current[key] === undefined) return undefined
+ current = current[key] }
+ return current }
+
+const arrity = (e, n) =>
+ { if (e.length !== n) err(`Expected ${n} arguments, got ${e.length}`) }
+
+const NATIVE =
+ { 'randInt': min => max => min + Math.floor(Math.random() * (max - min + 1)),
+ '+': a => b => a + b,
+ '==': a => b => a === b,
+ '|': a => b => a || b,
+ '!': a => !a,
+ // FIXME: function are eager, `if` need to be a keyword
+ // '?': a => b => c => a ? b : c,
+ 'print': s => console.log(s),
+ 'panic': e => console.log("Runtime Type Error:", e) }
+
+// KEYWORDS: let, do, fn, quote, case, return
+const eval = (e, ENV = {}) =>
+ { if (Array.isArray(e))
+ { if (e[0] === 'quote') { return e.slice(1) }
+ else if (e[0] === 'do')
+ { ENV = { ...ENV }
+ for (let i = 1; i < e.length; ++i) eval(e[i], ENV)
+ return ENV }
+ else if (e[0] === 'let')
+ { arrity(e, 3); const x = eval(e[2], ENV); ENV[e[1]] = x; return x }
+ else if (e[0] === 'fn')
+ { if (e.length > 3)
+ { const sugar = x =>
+ { if (x.length <= 3) return x
+ return ["fn", x[1], sugar(["fn", ...x.slice(2)])] }
+ return eval(sugar(e), ENV) }
+ arrity(e, 3)
+ return arg => eval(e[2], { ...ENV, [e[1]]: arg }) }
+ else if (e[0] === 'if')
+ { arrity(e, 4)
+ return eval(e[1], ENV) === true
+ ? eval(e[2], ENV)
+ : eval(e[3], ENV) }
+ else
+ { if (e.length > 2)
+ { const sugar = x =>
+ { if (x.length <= 2) return x
+ return [sugar(x.slice(0, x.length - 1)), x[x.length - 1]] }
+ return eval(sugar(e), ENV) }
+ arrity(e, 2)
+ let fn = e[0]
+ if (Array.isArray(fn)) fn = eval(fn, ENV)
+ if (typeof fn !== 'function')
+ { const x = get(ENV, fn)
+ if (x !== undefined) fn = x
+ else
+ { if (NATIVE[fn]) fn = NATIVE[fn]
+ else err(`Function ${fn} not found`) }
+ if (typeof fn !== 'function') err(`${fn} is not a function`) }
+ return fn(eval(e[1], ENV, true)) } }
+ else
+ { if (e === true || e === "true") return true
+ if (e === false || e === "false") return false
+ if (/^-?\d+$/.test(e)) return parseInt(e)
+ if (/^".*"$/.test(e)) return e.slice(1, -1)
+ else
+ { const x = get(ENV, e)
+ if (x !== undefined) return x
+ else err(`Variable ${e} not found`) } } }
+// `let` implicitly return the value assigned:
+assert(eval(parse(`(let x 42)`)) == 42)
+// ... but used within `do` block, it serve as field identifier:
+assert(eval(parse(`(do (let x (do (let y 42))))`)).x.y == 42)
+// `let` fields of a `do` struct could be accessed with `.` operator:
+assert(eval(parse(`(do (let x (do (let y 42))) (let z x.y))`)).z == 42)
+// instructions of a `do` block are evaluated in order:
+assert(eval(parse(`(do (let x 42) (let y x) (let z y))`)).z == 42)
+// and let definitions could be shadowed:
+assert(eval(parse(`(do (let x 40) (let x 41) (let x 42))`)).x == 42)
+// `do` blocks work as lexical scopes:
+assert(eval(parse(`(do (let x 42) (do (let x 0)))`)).x == 42)
+// `do` blocks could contains any instruction:
+assert(eval(parse(`(do (+ 2 2) (let x 42))`)).x == 42)
+// `fn` (function) support partial application:
+assert(eval(parse(`(do (let x (fn x (+ x)))` + // x is (fn x (+ x))
+ `(let x (x 2))` + // x is (+ 2)
+ `(let x (x 40))`) // x is ((+ 2) 40)
+).x == 42)
+// `fn` also capture their environment (here `y`):
+assert(eval(parse(`(do (let x 0)
+ (let y 1)
+ (let x ((fn x (+ y x)) 41)))`)).x == 42)
+// values: 42 41 1 41
+// `fn` have some nice syntaxic sugar, these 2 expressions are equivalents:
+assert(eval(parse(`((fn x (fn y ((+ x) y))) 2 40)`)) == 42)
+assert(eval(parse(`((fn x y ( + x y) ) 2 40)`)) == 42)
+// ... this is call curryfication!
+// Within a `do` block you can break the flow of computation by replacing the
+// struct by a specific value:
+// FIXME: assert(eval(parse(`(do (let x 42) (return x) (let x 0))`)) == 42)
+// n.b. Haskell/Nix/OCaml/Scheme let X (in) Y keywords could be emulate by:
+// (do (let X) (return Y))
+// FIXME: console.log(eval(parse(`(do (return (list A B C)))`)))
+// TODO: explain and test `quote` ...
+// eval(parse(`
+// (do
+// (let x (randInt 0 1))
+// (let y (if (== x 1)
+// "foo"
+// "bar"))
+// (print y)
+// (if (! (| "bar" "foo"))
+// (panic "Err")
+// (print "Ok")))
+// `)) // Print "foo\nOk"
+//
+// To be continued ...
A => experimental/gc.h +405 -0
@@ 0,0 1,405 @@
+/*
+ * This file should build without warning with clang version 14.0.0:
+ * > clang gc.h -std=c89
+ * I tested it also with gcc version 11.3.0:
+ * > gcc gc.h -std=c89
+ */
+
+#include <errno.h> /* Needed by strerror_r(errno, ...) */
+#include <stdio.h> /* Needed by fprintf(stderr, ...) */
+#include <stdlib.h> /* Needed by exit(EXIT_FAILURE) */
+#include <string.h> /* Needed by memset, memmove */
+#include <sys/mman.h> /* Needed by mmap, munmap, mremap */
+#include <unistd.h> /* Needed by sysconf(_SC_PAGE_SIZE) */
+/* #include <Windows.h> *//* Needed by VirtualAlloc, VirtualFree */
+
+/* TODO ... */
+/* #define NDEBUG */
+/* #include <assert.h> */
+
+/* Handy panic handlers defined later in this file ... */
+void gc_panic(const char* file, int line);
+void* gc_unwrap(void* value, const char* file, int line);
+#define panic() gc_panic(__FILE__, __LINE__)
+#define unwrap(value) gc_unwrap(value, __FILE__, __LINE__)
+
+/*
+ * Memory management primitives
+ * ----------------------------
+ *
+ * The purpose of this part is to define a gc_sbrk that allow memory allocation
+ * / liberation in roughly O(1) using internally mmap / munmap when such
+ * syscalls are OS defined.
+ *
+ * The memory is a continuous space of allocated adresse growing such as a heap
+ * segment would, we have few markers around our pages:
+ *
+ * ------ allocated memory adresses ---->
+ * |zzzzzzzz|yyyyy|xxxxxxxxxx|----------|~~
+ * start last used stop
+ *
+ * n.b. an alternative noncontinuous (hardened for security concern) version of
+ * this allocator is just a stack of pointer (and so would require one more
+ * indirection) ...
+ *
+ */
+
+static void* start = NULL;
+static void* last = NULL;
+static void* used = NULL;
+static void* stop = NULL;
+static size_t page_size = 0;
+
+/* TODO: This should better be a #define ... */
+void assert_gc_init(void) {
+ if (page_size == 0) {
+#ifdef _WIN32 /* Windows */
+ fprintf_s(stderr, "gc_init haven't be call before memory allocation\n");
+ ExitProcess(EXIT_FAILURE);
+#else /* Unix */
+ fprintf(stderr, "gc_init haven't be call before memory allocation\n");
+ exit(EXIT_FAILURE);
+#endif
+ }
+}
+
+#ifdef HARD_MODE
+
+/*
+ * HARD_MODE means "bring your memory" by giving to init function a start
+ * address and a size.
+ *
+ * TODO: should provide a callback mechanism to let user handle out-of-memory
+ * scenario gracefully.
+ */
+
+void gc_init_hard_mode(void* ptr, size_t size) {
+ start = last = used = ptr;
+ stop = ptr + size;
+}
+
+void* gc_sbrk(int increment) { /* TODO */ }
+
+/* if mmap() or VirtualAlloc() syscalls are available, then ... */
+#elif defined(_POSIX_MAPPED_FILES) || defined(_WIN32)
+
+/* gc_init should be call at the top of your main function */
+void gc_init(void) {
+#ifdef _WIN32 /* Windows */
+ SYSTEM_INFO sysInfo;
+ GetSystemInfo(&sysInfo);
+ page_size = sysInfo.dwPageSize;
+ start = last = used =
+ VirtualAlloc(NULL, page_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ if (start == NULL) {
+ fprintf_s(stderr, "Fail to initialize memory\n");
+ ExitProcess(EXIT_FAILURE);
+ }
+#else /* Unix */
+ page_size = sysconf(_SC_PAGE_SIZE);
+ start = last = used = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, -1, 0);
+ if (start == MAP_FAILED) {
+ fprintf(stderr, "Fail to initialize memory\n");
+ exit(EXIT_FAILURE);
+ }
+#endif
+ stop = start + page_size;
+}
+
+/*
+ * gc_sbrk - Custom implementation of the sbrk function using mmap and munmap
+ *
+ * @increment: the number of bytes to increment the break value by. If increment
+ * is negative, the equivalent amount of memory is deallocated. If increment is
+ * zero, the current break value is returned.
+ *
+ * Returns a pointer to the start of the newly allocated memory block, or NULL
+ * if the allocation failed.
+ */
+void* gc_sbrk(int increment) {
+ assert_gc_init();
+ void* current = stop;
+ if (increment > 0) {
+ int asked = ((increment / page_size) + 1) * page_size;
+#ifdef _WIN32 /* Windows */
+ void* ptr =
+ VirtualAlloc(stop, asked, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ if (ptr == NULL)
+ return NULL;
+#else /* Unix */
+ void* ptr = mmap(stop, asked, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, -1, 0);
+ if (ptr == MAP_FAILED)
+ return NULL;
+#endif
+ stop = ptr + asked;
+ }
+ if (increment < 0) {
+ int asked = ((-increment) / page_size) * page_size;
+#ifdef _WIN32 /* Windows */
+ if (asked > 0 && !VirtualFree(stop - asked, 0, MEM_RELEASE))
+ panic();
+#else /* Unix */
+ if (asked > 0 && munmap(stop - asked, asked) != 0)
+ panic();
+#endif
+ stop -= asked;
+ }
+ return current;
+}
+
+#else /* ... else, we rely on brk() ... */
+
+/* Warning: brk and sbrk are deprecated on macOS ... */
+void* gc_sbrk(int increment) {
+ assert_gc_init();
+ void* current = stop;
+ stop += increment;
+ if (brk(stop) != 0) {
+ return NULL;
+ }
+ return current;
+}
+
+void gc_init(void) {
+ page_size = sysconf(_SC_PAGE_SIZE);
+ stop = (void*) (long int) brk(NULL);
+ start = last = used = gc_sbrk(page_size);
+ if (start == NULL) {
+ fprintf(stderr, "Fail to initialize memory\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+#endif
+
+/*
+ * Memory management utilities
+ * ---------------------------
+ *
+ * Memory allocation utilities that behave like you would expect, EXCEPT for the
+ * gc_free function! The gc_free free all memory allocated since the allocation
+ * of the pointer given to it (n.b. gc_realloc count as a new allocation). You
+ * can see pointers as timestamp, in this model if you gc_malloc A, then B, then
+ * C, and then gc_free B, implicitly it means that you freed C. Another mental
+ * model around this mechanism is the stack: memory allocated is free in the
+ * reverse order of allocations.
+ */
+
+/*
+ * gc_malloc - Allocate memory block of given size
+ *
+ * @size: size of the memory block in bytes
+ *
+ * Returns a pointer to the allocated memory block
+ */
+void* gc_malloc(size_t size) {
+ int needed = used + size - stop;
+ if (needed > 0) {
+ if (gc_sbrk(needed) == NULL) {
+ errno = ENOMEM;
+ panic();
+ }
+ stop += needed;
+ }
+ void* ptr = used;
+ used += size;
+ last = ptr;
+ return ptr;
+}
+
+/*
+ * gc_calloc - Allocate and initialize memory block of given size
+ *
+ * @n: number of elements in the array
+ * @size: size of each element in bytes
+ *
+ * Returns a pointer to the allocated and initialized memory block
+ */
+void* gc_calloc(size_t n, size_t size) {
+ size *= n;
+ return memset(gc_malloc(size), 0, size);
+}
+
+/*
+ * gc_realloc - Reallocate memory block to a new size
+ *
+ * @ptr: pointer to the original memory block
+ * @size: new size of the memory block in bytes
+ *
+ * Returns a pointer to the reallocated memory block
+ */
+void* gc_realloc(void* ptr, size_t size) {
+ if (ptr == last)
+ used = last;
+ void* new_ptr = gc_malloc(size);
+ if (ptr != last && ptr != NULL)
+ memmove(new_ptr, ptr, size);
+ return new_ptr;
+}
+
+/*
+ * gc_free - Free allocated memory block
+ *
+ * @ptr: pointer to the memory block to be freed
+ */
+void gc_free(void* ptr) {
+ if (ptr == NULL || start > ptr || ptr > used)
+ return;
+ used = ptr;
+ int unused = stop - used;
+ if (gc_sbrk(-unused) != NULL)
+ stop -= unused;
+}
+
+/*
+ * Boxed utilities
+ * ---------------
+ *
+ * Keep track of the size of items allocated on the heap could be tiresome, here
+ * is a simple type and utilities to keep track of the size of memory allocated
+ * to a pointer in "boxed" fashion.
+ */
+
+typedef struct Box {
+ void* data;
+ size_t size;
+} Box;
+
+/* Boxed version of: void* gc_malloc(size_t size) */
+Box boxed_malloc(size_t size) {
+ Box ret = {gc_malloc(size), size};
+ return ret;
+}
+
+/* Boxed version of: void* gc_calloc(size_t n, size_t size) */
+Box boxed_calloc(size_t n, size_t size) {
+ Box ret = {gc_calloc(n, size), n * size};
+ return ret;
+}
+
+/* Boxed version of: void* gc_realloc(void* ptr, size_t size) */
+Box boxed_realloc(Box x, size_t size) {
+ Box ret = {gc_realloc(x.data, size), size};
+ return ret;
+}
+
+/* Boxed version of: void gc_free(void* ptr) */
+void boxed_free(Box x) {
+ gc_free(x.data);
+}
+
+/*
+ * Collector
+ * ---------
+ *
+ * TODO: This would be the core logic of the "destructor" mechanism, it should
+ * work recursively but for now only accept a dumb Box. Thanks to Nao, I will
+ * reimplement it using an OCaml like Object abstraction
+ * https://git.naomini.tel/nao/lysp/src/c-interp/object.c
+ *
+ * gc_collect take an object (or later a list of objects), and, in increasing
+ * pointer order, move objects (and compact memory) starting at target pointer
+ * address: target should be the value of the beginning of the heap region
+ * associated to your stack frame, you can obtain it using gc_malloc(0) at the
+ * start of your function definition.
+ *
+ * Then gc_collect will gc_free the memory after the last moved value. Collect
+ * has a heuristic criterion to save on moving values (e.g., the implementation
+ * doesn’t move overlapping memory). Here is a little schema:
+ *
+ * target
+ * |---------|---A---B----C---|
+ * *** collect(target, C) ***
+ * |---------|ABC|
+ */
+
+/*
+ * Increasing this value could speed up programs while being more greedy on
+ * memory usage ...
+ */
+#define HEURISTIC_VALUE 0
+
+void gc_collect(void* target, Box x) {
+ /* TODO: if ptr == NULL ... panic? */
+ if (target >= x.data || (x.data - target) < x.size + HEURISTIC_VALUE)
+ return;
+ /*
+ * #ifdef MREMAP_MAYMOVE
+ * TODO: There is likely a efficient memmove implementation using ...
+ * mremap(x.data, x.size, x.size, MREMAP_MAYMOVE | MREMAP_FIXED, target)
+ * ... and the right munmap combination on modern Linux!
+ */
+ memmove(target, x.data, x.size);
+ gc_free(target + x.size);
+}
+
+/*
+ * Panic handler
+ * -------------
+ *
+ * Just as a bonus, panic handler that magical unwind all allocated objects :)
+ */
+
+/*
+ * panic - Print error message and exit with failure status
+ *
+ * @file: file name where the error occurred
+ * @line: line number where the error occurred
+ */
+#ifdef _WIN32 /* Windows */
+
+void gc_panic(const char* file, int line) {
+ DWORD errorCode = GetLastError();
+ /*
+ * TODO: Windows syscalls doesn't use errno ... how boring to trigger
+ * cross-platform errors in my code ...
+ */
+ LPVOID lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0, NULL);
+ fprintf(stderr, "Error: %s\n", (char *)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ gc_free(start);
+ ExitProcess(EXIT_FAILURE);
+}
+
+#else /* Unix */
+
+void gc_panic(const char* file, int line) {
+ char buffer[256];
+ int result = strerror_r(errno, buffer, sizeof buffer);
+ if (result == 0) {
+ fprintf(stderr, "Error (%s:%d): %s\n", file, line, buffer);
+ } else {
+ fprintf(stderr, "Error (%s:%d): strerror_r() failed with error code %d\n",
+ file, line, result);
+ }
+ gc_free(start);
+ exit(EXIT_FAILURE);
+}
+
+#endif
+
+/*
+ * unwrap - Check if a value is NULL and call panic if it is
+ *
+ * @value: value to check
+ * @file: file name where the error occurred
+ * @line: line number where the error occurred
+ *
+ * Returns the value if it is not NULL
+ */
+void* gc_unwrap(void* value, const char* file, int line) {
+ if (value == NULL)
+ gc_panic(file, line);
+ return value;
+}
No newline at end of file
A => experimental/playground.html +13 -0
@@ 0,0 1,13 @@
+<script src="./tree-sitter.js"></script>
+<script>
+ const Parser = window.TreeSitter;
+ Parser.init().then(() =>
+ { const parser = new Parser();
+ parser.Language.load('../tree-sitter-bee-lang/tree-sitter-bee.wasm').then((BeeLang) =>
+ { parser.setLanguage(BeeLang);
+ const sourceCode = `{ x = x -> y -> add x y; y = x 2 3; }`;
+ const tree = parser.parse(sourceCode);
+ console.log(tree.rootNode.toString()); }); });
+ // To be continued ...
+ // https://github.com/tree-sitter/tree-sitter/tree/master/lib/binding_web
+</script>
A => flake.lock +130 -0
@@ 0,0 1,130 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1705309234,
+ "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_2": {
+ "inputs": {
+ "systems": "systems_2"
+ },
+ "locked": {
+ "lastModified": 1705309234,
+ "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1706683685,
+ "narHash": "sha256-FtPPshEpxH/ewBOsdKBNhlsL2MLEFv1hEnQ19f/bFsQ=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "5ad9903c16126a7d949101687af0aa589b1d7d3d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1706487304,
+ "narHash": "sha256-LE8lVX28MV2jWJsidW13D2qrHU/RUUONendL2Q/WlJg=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "90f456026d284c22b3e3497be980b2e47d0b28ac",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs",
+ "rust-overlay": "rust-overlay"
+ }
+ },
+ "rust-overlay": {
+ "inputs": {
+ "flake-utils": "flake-utils_2",
+ "nixpkgs": "nixpkgs_2"
+ },
+ "locked": {
+ "lastModified": 1706753617,
+ "narHash": "sha256-ZKqTFzhFwSWFEpQTJ0uXnfJBs5Y/po9/8TK4bzssdbs=",
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "58be43ae223034217ea1bd58c73210644031b687",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ },
+ "systems_2": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
A => flake.nix +16 -0
@@ 0,0 1,16 @@
+{
+ inputs = {
+ flake-utils.url = "github:numtide/flake-utils";
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ rust-overlay.url = "github:oxalica/rust-overlay";
+ };
+ outputs = { flake-utils, nixpkgs, rust-overlay, ... }:
+ flake-utils.lib.eachDefaultSystem (system:
+ let
+ overlays = [ (import rust-overlay) ];
+ pkgs = import nixpkgs { inherit system overlays; };
+ in {
+ defaultPackage = import ./default.nix { inherit pkgs system; };
+ devShell = import ./shell.nix { inherit pkgs system; };
+ });
+}
A => index.js +14 -0
@@ 0,0 1,14 @@
+// FIXME: implement a LSP and a DAP ...
+// https://code.visualstudio.com/api/language-extensions/language-server-extension-guide
+// https://microsoft.github.io/debug-adapter-protocol/
+
+const Parser = require('tree-sitter');
+const BeeLang = require('./tree-sitter-bee-lang');
+
+const parser = new Parser();
+parser.setLanguage(BeeLang);
+
+// const sourceCode = `{ x = x => y => add x y; y = x 2 3; }`;
+// const tree = parser.parse(sourceCode);
+
+// console.log(tree.rootNode.toString());
A => package-lock.json +475 -0
@@ 0,0 1,475 @@
+{
+ "name": "bee-lang",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "bee-lang",
+ "version": "0.1.0",
+ "license": "GPLv2",
+ "dependencies": {
+ "tree-sitter": "^0.20.6",
+ "tree-sitter-bee-lang": "file:tree-sitter"
+ }
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ },
+ "node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
+ "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
+ "node_modules/github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+ },
+ "node_modules/nan": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz",
+ "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w=="
+ },
+ "node_modules/napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+ },
+ "node_modules/node-abi": {
+ "version": "3.52.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.52.0.tgz",
+ "integrity": "sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ==",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/prebuild-install": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
+ "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^3.3.0",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^4.0.0",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0"
+ },
+ "bin": {
+ "prebuild-install": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "dependencies": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tree-sitter": {
+ "version": "0.20.6",
+ "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.6.tgz",
+ "integrity": "sha512-GxJodajVpfgb3UREzzIbtA1hyRnTxVbWVXrbC6sk4xTMH5ERMBJk9HJNq4c8jOJeUaIOmLcwg+t6mez/PDvGqg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "nan": "^2.18.0",
+ "prebuild-install": "^7.1.1"
+ }
+ },
+ "node_modules/tree-sitter-bee-lang": {
+ "resolved": "tree-sitter",
+ "link": true
+ },
+ "node_modules/tree-sitter-cli": {
+ "version": "0.20.8",
+ "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz",
+ "integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "tree-sitter": "cli.js"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "tree-sitter": {
+ "version": "0.1.0",
+ "hasInstallScript": true,
+ "license": "ISC",
+ "dependencies": {
+ "nan": "^2.18.0"
+ },
+ "devDependencies": {
+ "tree-sitter-cli": "^0.20.8"
+ }
+ },
+ "tree-sitter-bee-lang": {
+ "version": "0.0.1",
+ "extraneous": true,
+ "hasInstallScript": true,
+ "license": "ISC",
+ "dependencies": {
+ "nan": "^2.18.0"
+ },
+ "devDependencies": {
+ "tree-sitter-cli": "^0.20.8"
+ }
+ }
+ }
+}
A => package.json +12 -0
@@ 0,0 1,12 @@
+{
+ "name": "bee-lang",
+ "version": "0.1.0",
+ "description": "",
+ "main": "index.js",
+ "author": "Yvan Sraka <yvan@sraka.xyz>",
+ "license": "GPLv2",
+ "dependencies": {
+ "tree-sitter": "^0.20.6",
+ "tree-sitter-bee-lang": "file:tree-sitter"
+ }
+}
A => rust-toolchain +1 -0
A => shell.nix +24 -0
@@ 0,0 1,24 @@
+# If you plan to use `nix-shell` you have first to:
+#
+# $ nix-channel --add https://github.com/oxalica/rust-overlay/archive/master.tar.gz rust-overlay
+# $ nix-channel --update
+{ pkgs ? import <nixpkgs> { overlays = [ (import <rust-overlay>) ]; }
+, system ? builtins.currentSystem }:
+with pkgs;
+let
+ toolchain = (rust-bin.fromRustupToolchainFile ./rust-toolchain).override {
+ extensions = [ "rust-src" "rust-analyzer" "clippy" ];
+ };
+in mkShell {
+ buildInputs = [ nodejs toolchain tree-sitter ]
+ ++ (if system == "x86_64-linux" then [ mold ] else [ ]);
+ RUST_BACKTRACE = "full";
+ shellHook = ''
+ if [ ! -f "tree-sitter-bee-lang/src/parser.c" ]; then
+ pushd tree-sitter-bee-lang
+ tree-sitter generate
+ popd
+ fi
+ '';
+
+}
A => src/bin/bee/build.rs +175 -0
@@ 0,0 1,175 @@
+use bee::build::{build, Error, PRELUDE};
+use bee::cache::{cached, relative};
+use bee::cli::BuildArgs;
+use bee::codegen::{is_valid_extension, is_valid_filename};
+use bee::parser::Span;
+use log::{error, info, warn};
+use miette::miette;
+use owo_colors::{OwoColorize, Stream::Stdout, Style};
+use regex::Regex;
+use std::cmp::min;
+use std::collections::{BTreeSet, HashMap};
+use std::fs::{self, File};
+use std::io::{self, IsTerminal, Read, Write};
+
+/// TODO: write documentation...
+pub(crate) fn handle(args: &BuildArgs) -> exitcode::ExitCode {
+ let input_piped = !io::stdin().is_terminal();
+ let output_piped = !io::stdout().is_terminal();
+
+ if args.output.is_none() && !output_piped {
+ error!("output was not specified with `-o`/`--output` or stdout piped");
+ return exitcode::USAGE;
+ }
+ if args.input.is_some() && input_piped {
+ error!("I'm confuse, you specified both an input file and piped stdin");
+ return exitcode::USAGE;
+ }
+ if args.output.is_some() && output_piped {
+ error!(
+ "I'm confuse, you specified both an output file with `-o`/`--output` and piped stdout"
+ );
+ return exitcode::USAGE;
+ }
+
+ let src = if input_piped {
+ let mut src = String::new();
+ io::stdin().read_to_string(&mut src).unwrap();
+ src
+ } else {
+ let mut input = match &args.input {
+ Some(x) => x.clone(),
+ None => "./main.bee".into(),
+ };
+ if let Ok(metadata) = fs::metadata(&input) {
+ if metadata.is_dir() {
+ input = input.join("main.bee");
+ }
+ };
+ match fs::read_to_string(&input) {
+ Ok(src) => src,
+ Err(err) => {
+ error!("while reading file `{}`: {err}", input.display());
+ return exitcode::NOINPUT;
+ }
+ }
+ };
+ // FIXME: This error isn't really meaningful and isn't triggered if an empty
+ // file is imported ...
+ // if src.trim() == "" {
+ // error!("the given input file is empty");
+ // return exitcode::NOINPUT;
+ // }
+
+ let filename = if input_piped {
+ "/dev/stdin".into()
+ } else {
+ let path = match &args.input {
+ Some(x) => x.clone(),
+ None => "./main.bee".into(),
+ };
+ if let Ok(metadata) = fs::metadata(&path) {
+ if metadata.len() > 50000 {
+ warn!("file `{}` seems big, consider spliting it into modules to better use build cache", path.display());
+ }
+ }
+ if !is_valid_extension(&path) {
+ error!("file `{}` extension should be `.bee`", path.display());
+ return exitcode::USAGE;
+ }
+ if !is_valid_filename(&path) {
+ error!(
+ "file path `{}` contains illegal characters: `:`, `.`, `[` or `]`",
+ path.display()
+ );
+ return exitcode::USAGE;
+ }
+ fs::canonicalize(&path).unwrap()
+ };
+
+ let mut targets = match &args.targets {
+ Some(x) => Regex::new(r"[, ]").unwrap().split(x).collect(),
+ None => BTreeSet::new(),
+ };
+ if targets.contains("debug") && targets.contains("release") {
+ error!("both @debug and @release mutually exclusive targets are given as arguments");
+ return exitcode::USAGE;
+ }
+ if !targets.contains("release") {
+ targets.insert("debug");
+ }
+
+ match if input_piped {
+ warn!("build cache doesn't store piped input");
+ build(src.as_bytes(), &filename, &targets)
+ } else {
+ cached(src.as_bytes(), &filename, &targets, build)
+ } {
+ Ok(output) => {
+ // FIXME: print the `lazy_static` stack of WARNINGS on stderr
+ if output_piped {
+ println!("{}", output);
+ } else {
+ let mut file = File::create(args.output.clone().unwrap()).unwrap();
+ file.write_all(output.as_bytes()).unwrap();
+ }
+ exitcode::OK
+ }
+ Err(err) => {
+ error(err);
+ exitcode::DATAERR // FIXME: rather use a custom error > 78
+ }
+ }
+}
+
+fn error(err: Error) {
+ let Error {
+ msg,
+ code,
+ help,
+ stacktrace,
+ } = err;
+ println!();
+ error!(
+ "{} {}",
+ code.if_supports_color(Stdout, |text| text.style(Style::new().bold().red())),
+ msg, // FIXME: color every verbatim content between ``
+ );
+ if let Some(stacktrace) = stacktrace {
+ let total = min(5, stacktrace.len());
+ let stacktrace = &stacktrace[..total];
+ let mut map = HashMap::new();
+ for (index, span) in stacktrace.iter().enumerate() {
+ map.entry(span.filename.clone())
+ .or_insert_with(Vec::new)
+ .push((span, index));
+ }
+ let grouped_span_by_filename: Vec<Vec<(&Span, usize)>> = map.into_values().collect();
+ for spans in grouped_span_by_filename {
+ let filename = &spans[0].0.filename;
+ let src = if filename.display().to_string() == "prelude" {
+ PRELUDE.to_owned()
+ } else {
+ fs::read_to_string(filename).unwrap()
+ };
+ let named_src = miette::NamedSource::new(relative(filename).display().to_string(), src);
+ let labels: Vec<_> = spans
+ .iter()
+ .map(|span| {
+ miette::LabeledSpan::at(
+ span.0.clone().byte_range,
+ format!("{}/{total}", span.1 + 1),
+ )
+ })
+ .collect();
+ let report = match help {
+ Some(ref help) => miette!(help = help, labels = labels, ""),
+ None => miette!(labels = labels, ""),
+ };
+ eprint!("{:?}", report.with_source_code(named_src));
+ }
+ } else if let Some(help) = help {
+ info!("help: {help}");
+ }
+ // FIXME: println!("\n... to display a more verbose message use: {}", format!("bee explain {code}"));
+}
A => src/bin/bee/cache.rs +78 -0
@@ 0,0 1,78 @@
+use bee::cache::CACHE_ROOT;
+use bee::cli::CacheArgs;
+use log::{error, info};
+use std::fs;
+use std::path::Path;
+use walkdir::WalkDir;
+
+/// TODO: write documentation...
+pub(crate) fn handle(args: &CacheArgs) -> exitcode::ExitCode {
+ match args {
+ CacheArgs::Clear(args) => {
+ if args.all && args.input.is_some() {
+ error!("I'm confused ... you give to `bee cache` command an input and the `--all` arg, there are mutually exclusive");
+ return exitcode::USAGE;
+ }
+ if !args.all && args.input.is_none() {
+ error!("`bee cache` command take either an input or the `--all` arg (that remove all of the global build cache)");
+ return exitcode::USAGE;
+ }
+ if args.all {
+ if CACHE_ROOT.exists() {
+ fs::remove_dir_all(CACHE_ROOT.clone()).unwrap();
+ }
+ info!("The build cache have been globally cleared.");
+ }
+ if let Some(input) = &args.input {
+ // FIXME: be able to remove a file or folder in cache that does not exist on filesystem
+ if !input.exists() {
+ error!("file or folder {} does not exist", input.display());
+ return exitcode::NOINPUT;
+ }
+ let cache_path = &CACHE_ROOT.join(fs::canonicalize(input).unwrap());
+ if cache_path.is_dir() {
+ fs::remove_dir_all(cache_path).unwrap();
+ }
+ if cache_path.is_file() {
+ fs::remove_file(cache_path).unwrap();
+ fs::remove_file(cache_path.with_extension("deps")).unwrap();
+ }
+ }
+ exitcode::OK
+ }
+ CacheArgs::Gc => {
+ for entry in WalkDir::new(CACHE_ROOT.clone()) {
+ let entry = entry.unwrap();
+ if entry.file_type().is_file() {
+ let cache_path = entry.path();
+ if cache_path.extension().unwrap() == "js" {
+ let path = cache_path.display().to_string();
+ let path = path
+ .strip_prefix(&CACHE_ROOT.display().to_string())
+ .unwrap();
+ // FIXME: this will not play well with filename
+ // containing `.` (other than the `.bee` extension) ...
+ let path = format!("{}.bee", path.split('.').collect::<Vec<&str>>()[0]);
+ let path = Path::new(&path);
+ // FIXME: understand why it's /.prelude... and not /prelude...
+ if !path.exists() && !path.display().to_string().starts_with("/.") {
+ fs::remove_file(cache_path).unwrap();
+ fs::remove_file(cache_path.with_extension("deps")).unwrap();
+ info!("Cleared `{}` from build cache ...", path.display())
+ }
+ }
+ }
+ }
+ info!("The build cache garbage-collection (GC) is completed.");
+ exitcode::OK
+ }
+ CacheArgs::Prune(_) => {
+ error!("`bee cache prune` command is not yet implemented");
+ info!(
+ "To keep up-to-date with the project, subscribe to \"announce\" mailing-list:
+https://lists.sr.ht/~yvan-sraka/bee-lang-announce"
+ );
+ exitcode::UNAVAILABLE
+ }
+ }
+}
A => src/bin/bee/explain.rs +12 -0
@@ 0,0 1,12 @@
+use bee::cli::ExplainArgs;
+use log::{error, info};
+
+/// TODO: write documentation...
+pub(crate) fn handle(_args: &ExplainArgs) -> exitcode::ExitCode {
+ error!("`bee explain` command is not yet implemented");
+ info!(
+ "To keep up-to-date with the project, subscribe to \"announce\" mailing-list:
+https://lists.sr.ht/~yvan-sraka/bee-lang-announce"
+ );
+ exitcode::UNAVAILABLE
+}
A => src/bin/bee/main.rs +84 -0
@@ 0,0 1,84 @@
+mod build;
+mod cache;
+mod explain;
+mod run;
+
+use bee::cli::{Cli, Commands};
+use clap::{CommandFactory, Parser};
+#[cfg(debug_assertions)]
+use log::warn;
+use owo_colors::{OwoColorize, Stream::Stdout, Style};
+use std::io::Write;
+
+fn main() {
+ let env = env_logger::Env::default()
+ .filter_or("BEE_LOG", "info")
+ .write_style_or("BEE_LOG_STYLE", "auto");
+ env_logger::Builder::from_env(env)
+ .format(|buf, record| {
+ writeln!(
+ buf,
+ "{}{}",
+ match record.level() {
+ log::Level::Error => "error: "
+ .if_supports_color(Stdout, |text| text.style(Style::new().red().bold()))
+ .to_string(),
+ log::Level::Warn => "warning: "
+ .if_supports_color(Stdout, |text| text.style(Style::new().yellow().bold()))
+ .to_string(),
+ log::Level::Info => "".to_owned(),
+ log::Level::Debug => "debug: ".to_owned(),
+ log::Level::Trace => "trace: ".to_owned(),
+ },
+ record.args()
+ )
+ })
+ .init();
+ #[cfg(debug_assertions)]
+ warn!("you use a debug build of bee, the build cache is disabled");
+ #[cfg(not(debug_assertions))]
+ human_panic::setup_panic!();
+ // FIXME: I forked `human_panic` to customize the message:
+ // let prev = std::panic::take_hook();
+ // std::panic::set_hook(Box::new(move |info| {
+ // prev(info);
+ // }));
+
+ // FIXME: This break NO_COLOR support, so I forked `miette` ...
+ // miette::set_hook(Box::new(|_| {
+ // Box::new(
+ // miette::MietteHandlerOpts::new()
+ // .graphical_theme(miette::GraphicalTheme {
+ // characters: miette::ThemeCharacters {
+ // warning: "".into(),
+ // error: "".into(),
+ // advice: "".into(),
+ // ..miette::ThemeCharacters::unicode()
+ // },
+ // ..Default::default()
+ // })
+ // .build(),
+ // )
+ // }))
+ // .unwrap();
+
+ let args = std::env::args().collect::<Vec<String>>();
+ if args.contains(&"--help".to_string()) || args.contains(&"-h".to_string()) {
+ Cli::command().print_help().unwrap();
+ println!(
+ "
+To keep up-to-date with the project, subscribe to \"announce\" mailing-list:
+https://lists.sr.ht/~yvan-sraka/bee-lang-announce bzz bzz bzz"
+ );
+ std::process::exit(0);
+ }
+
+ let cli = Cli::parse();
+
+ std::process::exit(match &cli.command {
+ Commands::Build(args) => build::handle(args),
+ Commands::Cache(args) => cache::handle(args),
+ Commands::Run(args) => run::handle(args),
+ Commands::Explain(args) => explain::handle(args),
+ });
+}
A => src/bin/bee/run.rs +12 -0
@@ 0,0 1,12 @@
+use bee::cli::RunArgs;
+use log::{error, info};
+
+/// TODO: write documentation...
+pub(crate) fn handle(_args: &RunArgs) -> exitcode::ExitCode {
+ error!("`bee run` command is not yet implemented");
+ info!(
+ "To keep up-to-date with the project, subscribe to \"announce\" mailing-list:
+https://lists.sr.ht/~yvan-sraka/bee-lang-announce"
+ );
+ exitcode::UNAVAILABLE
+}
A => src/build.rs +58 -0
@@ 0,0 1,58 @@
+use crate::codegen::{codegen, targets_codegen};
+use crate::eval::eval;
+use crate::parser::{parse, Span};
+use log::{trace, warn};
+use std::collections::BTreeSet;
+use std::path::Path;
+use std::sync::{Arc, Mutex};
+
+/// TODO: write documentation...
+pub const PRELUDE: &str = include_str!("./prelude.bee");
+
+lazy_static! {
+ /// TODO: write documentation...
+ static ref WARNINGS: Arc<Mutex<Vec<Error>>> =
+ Arc::new(Mutex::new(vec![]));
+}
+
+/// Custom error type that is use to produce a compiler error
+#[derive(Debug)]
+pub struct Error {
+ /// TODO: write documentation...
+ pub code: String, // FIXME: error code should be an enum!
+ /// TODO: write documentation...
+ pub msg: String,
+ /// TODO: write documentation...
+ pub stacktrace: Option<Vec<Span>>,
+ /// TODO: write documentation...
+ pub help: Option<String>,
+}
+
+/// TODO: write documentation...
+pub fn build(src: &[u8], filename: &Path, targets: &BTreeSet<&str>) -> Result<String, Error> {
+ // FIXME: give a try to `imbl` crate rather than cloning a BTreeSet ...
+ let mut targets = targets.clone();
+ if targets.contains("abstract") {
+ warn!("@abstract target is reserved to compiler internals and is ignored when passed as CLI argument")
+ }
+ let tree = parse(src);
+ trace!("Parsing ... done");
+ // FIXME: typing (abstract interpretation of program) should not be ran if
+ // a .bee.t file already exist and is more recent than the .bee file built
+ targets.insert("abstract");
+ let js = codegen(&tree, src, filename, &targets)?;
+ // ... yes yes ... we run codegen BEFORE typing ...
+ trace!("Codegen ... done");
+ // FIXME: had a --disable-checks CLI arg that remove this step?
+ eval(format!("{}{js}", targets_codegen(&targets)))?;
+ targets.remove("abstract");
+ trace!("Typing ... done");
+ let js = codegen(&tree, src, filename, &targets)?;
+ // FIXME: have a @release target that minify the output ...
+ // ... e.g. with https://github.com/wilsonzlin/minify-js
+ Ok(format!(
+ "{}{js}
+module.exports = __bee_export;",
+ targets_codegen(&targets)
+ ))
+}
A => src/cache.rs +139 -0
@@ 0,0 1,139 @@
+use crate::build::Error;
+use crate::VERSION;
+use directories::ProjectDirs;
+use log::info;
+use owo_colors::{OwoColorize, Stream::Stdout, Style};
+use std::collections::{BTreeSet, HashMap};
+use std::env;
+#[cfg(not(debug_assertions))]
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::sync::{Arc, Mutex};
+
+lazy_static! {
+ /// TODO: write documentation...
+ static ref DEPENDENCIES: Arc<Mutex<HashMap<PathBuf, Vec<PathBuf>>>> =
+ Arc::new(Mutex::new(HashMap::new()));
+ /// TODO: write documentation...
+ pub static ref CACHE_ROOT: PathBuf = ProjectDirs::from("org", "yvan-sraka", "bee-lang")
+ .unwrap()
+ .cache_dir()
+ .join(VERSION);
+ /// TODO: write documentation...
+ static ref CURRENT_DIR: PathBuf = env::current_dir().unwrap();
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub(crate) fn register_dependency(filename: &Path, dependency: &Path) {
+ DEPENDENCIES
+ .lock()
+ .unwrap()
+ .entry(filename.into())
+ .or_default()
+ .push(dependency.into());
+}
+
+#[cfg(not(debug_assertions))]
+fn dependencies_changed(cache_file: &Path, targets: &BTreeSet<&str>) -> bool {
+ let mut deps_file = cache_file.to_path_buf();
+ deps_file.set_extension("deps");
+ for dep in fs::read_to_string(&deps_file).unwrap().lines() {
+ let dep = Path::new(dep);
+ match use_cached_version(dep, targets) {
+ Ok(_) => {}
+ Err(_) => return true,
+ }
+ }
+ false
+}
+
+#[cfg(not(debug_assertions))]
+fn use_cached_version(filename: &Path, targets: &BTreeSet<&str>) -> Result<PathBuf, PathBuf> {
+ let mut cached_file = CACHE_ROOT.join(format!(".{}", filename.display()));
+ cached_file.set_extension(format!(
+ "{}.js",
+ targets
+ .iter()
+ .map(|x| x.to_owned())
+ .collect::<Vec<&str>>()
+ .join(".")
+ ));
+ if cached_file.exists()
+ && (filename.display().to_string() == "prelude"
+ || (cached_file.metadata().unwrap().modified().unwrap()
+ > filename.metadata().unwrap().modified().unwrap()
+ && !dependencies_changed(&cached_file, targets)))
+ {
+ Ok(cached_file)
+ } else {
+ Err(cached_file)
+ }
+}
+
+type Builder = fn(&[u8], &Path, &BTreeSet<&str>) -> Result<String, Error>;
+
+/// TODO: write documentation...
+pub fn cached(
+ src: &[u8],
+ filename: &Path,
+ targets: &BTreeSet<&str>,
+ callback: Builder,
+) -> Result<String, Error> {
+ #[cfg(debug_assertions)]
+ {
+ build_log(filename, targets, false);
+ callback(src, filename, targets)
+ }
+ // Disabling caching in debug mode save hours as you may not want to return
+ // artifacts that doesn't reflect your changes as you're hacking on the
+ // compiler ;)
+ #[cfg(not(debug_assertions))]
+ Ok(match use_cached_version(filename, targets) {
+ Ok(cached_file) => {
+ build_log(filename, targets, true);
+ fs::read_to_string(cached_file).unwrap()
+ }
+ Err(cached_file) => {
+ build_log(filename, targets, false);
+ let result = callback(src, filename, targets)?;
+
+ fs::create_dir_all(cached_file.parent().unwrap()).unwrap();
+ fs::write(&cached_file, &result).unwrap();
+
+ let mut deps_file = cached_file.to_path_buf();
+ deps_file.set_extension("deps");
+ let deps = match DEPENDENCIES.lock().unwrap().get(filename) {
+ Some(x) => x
+ .iter()
+ .map(|x| x.display().to_string())
+ .collect::<Vec<_>>()
+ .join("\n"),
+ None => "".to_owned(),
+ };
+ fs::write(&deps_file, deps).unwrap();
+
+ result
+ }
+ })
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+fn build_log(filename: &Path, targets: &BTreeSet<&str>, cached: bool) {
+ if !targets.contains("abstract") {
+ info!(
+ "Building {} {}...",
+ relative(filename)
+ .display()
+ .if_supports_color(Stdout, |text| text.style(Style::new().bold().bright_cyan())),
+ if cached { "(cached) " } else { "" }
+ );
+ }
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn relative(path: &Path) -> PathBuf {
+ pathdiff::diff_paths(path, CURRENT_DIR.to_owned()).unwrap_or(path.to_owned())
+}
A => src/cli.rs +87 -0
@@ 0,0 1,87 @@
+use std::path::PathBuf;
+
+/// 🌸 🌼 🐝 The Bee programming language compiler 🌺 🌼 🌸
+#[derive(clap::Parser, Debug)]
+#[clap(author, version, about, long_about = None)]
+pub struct Cli {
+ #[clap(subcommand)]
+ pub command: Commands,
+}
+
+/// Main list of commands that can take `bee` CLI as argument
+#[derive(clap::Subcommand, Debug)]
+pub enum Commands {
+ /// Builds a given file or the `main.bee` within a given folder (by default the current folder)
+ Build(BuildArgs),
+ /// Manage build cache used by Bee compiler
+ #[clap(subcommand)]
+ Cache(CacheArgs),
+ /// Print a more verbose explaination for a given compiler error code
+ Explain(ExplainArgs),
+ /// Run a given script without compiling it to ECMAScript
+ Run(RunArgs),
+ // FIXME: add REPL command ... with cool message explaining the feature is missing :'(
+}
+
+/// Arguments for the `build` command
+#[derive(clap::Parser, Debug)]
+pub struct BuildArgs {
+ /// Input file name (.bee), that can also be piped in
+ pub input: Option<PathBuf>,
+
+ /// Output file name (.js), that can also be piped out
+ #[clap(short, long)]
+ pub output: Option<PathBuf>,
+
+ /// List of (comma or space separated) compiler targets
+ #[clap(short, long)]
+ pub targets: Option<String>,
+}
+
+/// Subcommands of the `cache` command
+#[derive(clap::Subcommand, Debug)]
+pub enum CacheArgs {
+ /// Clears the cache based on various criteria
+ Clear(CacheClearArgs),
+ /// Performs garbage collection on the cache, removing entries for files that no longer exist in the user’s file system
+ Gc,
+ /// Removes items from the cache based on age
+ Prune(CachePruneArgs),
+}
+
+/// TODO: write documentation...
+#[derive(clap::Parser, Debug)]
+pub struct CacheClearArgs {
+ /// Clears the cache for a specific path (file or folder)
+ pub input: Option<PathBuf>,
+
+ /// Clears the cache for a specific file and its dependencies
+ #[clap(short, long)]
+ pub deps: Option<String>,
+
+ /// Clears the entire build cache
+ #[clap(short, long)]
+ pub all: bool,
+ // FIXME: let user pass a --targets argument to allow more fine grained
+ // control over cache management?
+}
+
+/// TODO: write documentation...
+#[derive(clap::Parser, Debug)]
+pub struct CachePruneArgs {
+ /// Removes cache items that were created before a specific date
+ #[clap(short, long)]
+ before: Option<String>,
+
+ /// Removes cache items that are older than a specified duration (e.g., “30d” for 30 days)
+ #[clap(short, long)]
+ older_than: Option<String>,
+}
+
+/// TODO: write documentation...
+#[derive(clap::Parser, Debug)]
+pub struct ExplainArgs;
+
+/// TODO: write documentation...
+#[derive(clap::Parser, Debug)]
+pub struct RunArgs;
A => src/codegen.rs +641 -0
@@ 0,0 1,641 @@
+use crate::build::{Error, PRELUDE};
+use crate::cache::{cached, register_dependency};
+#[cfg(feature = "rayon")]
+use crate::parser::Nodes;
+use crate::parser::{parse, Span};
+#[cfg(feature = "rayon")]
+use rayon::prelude::*;
+use regex::{Captures, Regex};
+use std::collections::BTreeSet;
+use std::fs;
+use std::path::{Path, PathBuf};
+
+/// This is a naive approach to code generation intended for experimenting with
+/// the semantics of a Bee program.
+///
+/// The main idea is to generate JS values that can be embedded in a JS script.
+/// For example, the Bee expression `[1 2 3]` should produce JS code that, once
+/// evaluated, equals `[1, 2, 3]`.
+///
+/// The code generation should be capable of taking as input both the AST built
+/// by parsing (as it currently does) and an AST augmented with type
+/// annotations (and other invariants) inferred from static analysis. These
+/// annotations will be cached in a `.bee.t` file, which users are advised to
+/// distribute with their script.
+///
+/// This setup will enable a fast build mode (without typing if `.bee.t` is
+/// missing) and a slow one (typing is required if `.bee.ts` is missing or
+/// outdated). The fast compilation mode could be dropped if a Bee VM is
+/// implemented, as users who want to quickly evaluate their programs might
+/// prefer an interpreter over a compiler.
+///
+/// Currently, there is a WIP JavaScript implementation of a VM. One strategy
+/// could then be to perform codegen by simply serializing the AST to JSON and
+/// appending the JS runtime next to it. The generated JS will likely not be
+/// handled efficiently by JavaScript's JIT and tooling, but this approach
+/// allows more room for implementing reflexivity features without relying on
+/// JS's `eval`.
+///
+/// Currently, the codegen always adds debug symbols to the JS output, but this
+/// should be made optional. For example, a `--release` mode could omit the
+/// symbols and run a JS minification pass.
+pub fn codegen(
+ tree: &tree_sitter::Tree,
+ src: &[u8],
+ filename: &Path,
+ targets: &BTreeSet<&str>,
+) -> Result<String, Error> {
+ let prelude = PRELUDE.as_bytes();
+ Ok(format!(
+ "// RUNTIME
+{}
+// PRELUDE
+__bee_env = {};
+// USER CODE
+const __bee_export = {};
+",
+ include_str!("./runtime.js"),
+ cached(prelude, Path::new("prelude"), targets, codegen_module)?,
+ rec_codegen(&tree.root_node(), src, filename, targets)?
+ ))
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn codegen_module(
+ src: &[u8],
+ filename: &Path,
+ targets: &BTreeSet<&str>,
+) -> Result<String, Error> {
+ rec_codegen(&parse(src).root_node(), src, filename, targets)
+}
+
+fn rec_codegen(
+ node: &tree_sitter::Node,
+ src: &[u8],
+ filename: &Path,
+ targets: &BTreeSet<&str>,
+) -> Result<String, Error> {
+ let kind = node.kind();
+
+ let span = Span {
+ byte_range: node.byte_range(),
+ filename: filename.to_owned(),
+ };
+
+ if node.is_error() || node.is_missing() {
+ // FIXME: have a codegen::Error type
+ Err(Error {
+ msg: format!(
+ "parsing error{}",
+ if node.is_missing() {
+ format!(": `{}` is missing", kind)
+ } else {
+ "".to_owned()
+ }
+ ),
+ help: hint(node.utf8_text(src).unwrap()),
+ stacktrace: Some(vec![span.clone()]),
+ code: "PA001".to_owned(),
+ })?;
+ }
+
+ let children = (0..node.child_count())
+ .map(|i| node.child(i).unwrap())
+ .filter(|x| {
+ !matches!(
+ x.kind(),
+ "," | ";"
+ | "."
+ | "..."
+ | "("
+ | ")"
+ | "["
+ | "]"
+ | "{"
+ | "}"
+ | "\n"
+ | "="
+ | "=>"
+ | "$"
+ | "block_comment"
+ | "inline_comment"
+ | "else"
+ | "if"
+ | "import"
+ | "native"
+ | "panic"
+ | "return"
+ | "then"
+ )
+ })
+ .collect::<Vec<tree_sitter::Node>>();
+
+ Ok(match kind {
+ "apply" => {
+ let xs = children_codegen(children, src, filename, targets)?;
+ let id = &xs[0];
+ let args = xs[1..].join(", ");
+ format!("__bee_fn_apply({id}, [{args}], \"{span}\")")
+ }
+
+ "arg" | "bool" | "delimiter" | "expr" | "field" | "source_file" | "statement" | "value" => {
+ children_codegen(children, src, filename, targets)?.join("")
+ }
+
+ "id" => {
+ // FIXME: warning if `_` is used as an `id` unless it's an lambda `arg`
+ let id = children_codegen(children, src, filename, targets)?.join(", ");
+ format!("__bee_get_id(__bee_env, [{id}], \"{span}\")")
+ }
+
+ "name" => {
+ let name = node.utf8_text(src).unwrap();
+ let help = if name == "return" {
+ Some("`return` could be use only directly inside a block. e.g. `{ a = 1; b = 2; return {a} }`".to_owned())
+ } else {
+ None
+ };
+ if is_reserved_keywords(name) {
+ Err(Error {
+ msg: format!(
+ "use of the reserved keyword `{name}` as an identifier is forbidden"
+ ),
+ help,
+ stacktrace: Some(vec![span]),
+ code: "PA002".to_owned(),
+ })?
+ }
+ format!("\"{name}\"")
+ }
+
+ "nth" => node.utf8_text(src).unwrap().to_owned(),
+
+ "placeholder" => {
+ debug_assert!(children.len() == 1);
+ rec_codegen(&children[0], src, filename, targets)?
+ }
+
+ "true" => "true".to_owned(),
+ "false" => "false".to_owned(),
+
+ "target" => {
+ let x = &node.utf8_text(src).unwrap()[1..];
+ format!("__bee_targets.{x}")
+ }
+
+ "bigint" => {
+ let x = node.utf8_text(src).unwrap();
+ format!("{x}n")
+ }
+
+ "f64" => {
+ let x: f64 = node.utf8_text(src).unwrap().parse().unwrap();
+ x.to_string()
+ }
+
+ "string" => {
+ // FIXME: Rust strings are UTF-8, but JavaScript ones are UTF-16 ...
+ let haystack = node.utf8_text(src).unwrap();
+ let pattern = Regex::new(r"\$\{([^}]+)\}").unwrap();
+ for caps in pattern.captures_iter(haystack) {
+ let name = &caps[1];
+ let re = Regex::new(r"^[a-zA-Z_][a-zA-Z0-9_]*$").unwrap();
+ if !re.is_match(name) {
+ return Err(Error { code: "PA008".to_owned(), msg: format!("`{name}` is invalid, only simple identifiers can be interpolated in string."), stacktrace: Some(vec![span]), help: None });
+ }
+ }
+ pattern
+ .replace_all(haystack, |caps: &Captures| {
+ let name = &caps[1];
+ format!("\" + __bee_get_id(__bee_env, [\"{name}\"], \"{span}\") + \"")
+ })
+ .to_string()
+ }
+
+ "do" => {
+ let block = children_codegen(children, src, filename, targets)?.join(";\n");
+ format!(
+ "(__bee_env => {{
+ __bee_env.self = __bee_env;
+ {block}
+ return __bee_env_untag(__bee_env);
+}})(__bee_env_tag(__bee_env))"
+ )
+ }
+
+ // FIXME: pattern match on arguments!
+ "fn" => {
+ debug_assert!(children.len() == 2);
+ let arg = children[0].utf8_text(src).unwrap();
+ let value = rec_codegen(&children[1], src, filename, targets)?;
+ format!(
+ "(__bee_env_captured => {{
+ __bee_env_captured.self = __bee_env.self;
+ return __bee_arg => {{
+ const __bee_env = __bee_env_captured;
+ __bee_env.{arg} = __bee_arg;
+ return {value};
+ }};
+}})(__bee_env_copy(__bee_env))",
+ )
+ }
+
+ "if_then_else" => {
+ debug_assert!(children.len() == 3);
+ let xs = &children_codegen(children, src, filename, targets)?;
+ // FIXME: this is a hack ... add @concrete target? do this for any target ...
+ if targets.contains("abstract") {
+ return Ok(if xs[0] == "__bee_targets.abstract" {
+ &xs[1]
+ } else {
+ &xs[2]
+ }
+ .to_owned());
+ }
+ // FIXME: on @abstract a different codegen should be used!
+ format!("({} ? {} : {})", xs[0], xs[1], xs[2])
+ }
+
+ "let" => {
+ debug_assert!(children.len() == 2);
+ let lvalue = children[0].utf8_text(src).unwrap();
+ let rvalue = rec_codegen(&children[1], src, filename, targets)?;
+ let lvalue_span = Span {
+ byte_range: children[0].byte_range(),
+ ..span.clone()
+ };
+ if is_reserved_keywords(lvalue) {
+ Err(Error {
+ msg: format!("use of the reserved keyword `{lvalue}` as l-value is forbidden"),
+ help: None,
+ stacktrace: Some(vec![lvalue_span]),
+ code: "PA003".to_owned(),
+ })?
+ } else if lvalue == "_" || lvalue == "self" {
+ Err(Error {
+ msg: format!("`${lvalue}` should not be used as an l-value"),
+ help: None,
+ stacktrace: Some(vec![lvalue_span]),
+ code: "PA004".to_owned(),
+ })?
+ } else {
+ format!("__bee_env.{lvalue} = {rvalue}")
+ }
+ }
+
+ // FIXME: code is duplicated form `let` codegen ...
+ "name_alias" => {
+ debug_assert!(children.len() == 1);
+ let lvalue = children[0].utf8_text(src).unwrap();
+ let rvalue = format!("__bee_get_id(__bee_env, [\"{lvalue}\"], \"{span}\")");
+ if is_reserved_keywords(lvalue) {
+ Err(Error {
+ msg: format!("use of the reserved keyword `{lvalue}` as l-value is forbidden"),
+ help: None,
+ stacktrace: Some(vec![span]),
+ code: "PA003".to_owned(),
+ })?
+ } else if lvalue == "_" || lvalue == "self" {
+ Err(Error {
+ msg: format!("`${lvalue}` should not be used as an l-value"),
+ help: None,
+ stacktrace: Some(vec![span]),
+ code: "PA004".to_owned(),
+ })?
+ } else {
+ format!("__bee_env.{lvalue} = {rvalue}")
+ }
+ }
+
+ "spread" => {
+ debug_assert!(children.len() == 1);
+ let id = children[0].utf8_text(src).unwrap();
+ let rvalue = format!("__bee_get_id(__bee_env, [\"{id}\"], \"{span}\")");
+ format!("__bee_env = {{...__bee_env, ...{rvalue}}}")
+ }
+
+ "array" => {
+ let array = children_codegen(children, src, filename, targets)?.join(", ");
+ format!("[{array}]")
+ }
+
+ "panic_" => {
+ debug_assert!(children.len() == 1);
+ let rvalue = rec_codegen(&children[0], src, filename, targets)?;
+ format!("__bee_error(\"RT001\", {rvalue}, \"{span}\")")
+ }
+
+ "return_" => {
+ debug_assert!(children.len() == 1);
+ let rvalue = rec_codegen(&children[0], src, filename, targets)?;
+ format!("return {rvalue}")
+ }
+
+ // FIXME: a warning should be displayed to user when `native` keyword
+ // is used outside of prelude
+ "native_" => {
+ debug_assert!(children.len() == 1);
+ // FIXME: forbid the use of `native` in @abstract mode, this will
+ // force a better separation of concerns ...
+ // if targets.contains("abstract") {
+ // "{}".to_owned()
+ // } else ...
+ let haystack = children[0].utf8_text(src).unwrap().replace("\\\"", "\"");
+ let pattern = Regex::new(r"\$\{([^}]+)\}").unwrap();
+ for caps in pattern.captures_iter(&haystack) {
+ let name = &caps[1];
+ let re = Regex::new(r"^[a-zA-Z_][a-zA-Z0-9_]*$").unwrap();
+ if !re.is_match(name) {
+ return Err(Error { code: "PA008".to_owned(), msg: format!("`{name}` is invalid, only simple identifiers can be interpolated in string."), stacktrace: Some(vec![span]), help: None });
+ }
+ }
+ let interpolated = pattern.replace_all(&haystack, |caps: &Captures| {
+ let name = &caps[1];
+ format!("__bee_get_id(__bee_env, [\"{name}\"], \"{span}\")")
+ });
+ strip_quotes(&interpolated)
+ }
+
+ "import_" => {
+ // FIXME: support URLs (pointing e.g. to a git repository or a code
+ // archive). This is not trivial to implement as it should require
+ // e.g. some TOFU mechanism that store a checksum of the remote
+ // ressource in a .lock file that could be distributed with user
+ // sources.
+ debug_assert!(children.len() == 1);
+ let mut import = PathBuf::from(filename)
+ .parent()
+ .unwrap()
+ .join(strip_quotes(children[0].utf8_text(src).unwrap()));
+ if let Ok(metadata) = fs::metadata(&import) {
+ if metadata.is_dir() {
+ import = import.join("main.bee");
+ }
+ };
+ if !is_valid_extension(&import) {
+ Err(Error {
+ msg: format!("File `{}` extension should be `.bee`", import.display()),
+ help: None,
+ stacktrace: Some(vec![Span {
+ byte_range: children[0].byte_range(),
+ ..span.clone()
+ }]),
+ code: "PA006".to_owned(),
+ })?
+ }
+ if !is_valid_filename(&import) {
+ Err(Error {
+ msg: format!(
+ "File path `{}` contains illegal characters: `:`, `.`, `[` or `]`",
+ import.display()
+ ),
+ help: None,
+ stacktrace: Some(vec![Span {
+ byte_range: children[0].byte_range(),
+ ..span.clone()
+ }]),
+ code: "PA007".to_owned(),
+ })?
+ }
+ match std::fs::read_to_string(&import) {
+ Ok(src) => {
+ let src = src.as_bytes();
+ let import = fs::canonicalize(import).unwrap();
+ register_dependency(filename, &import);
+ cached(src, &import, targets, codegen_module)?
+ }
+ Err(err) => Err(Error {
+ msg: format!("error while reading file {}: {err}", &import.display()),
+ help: None,
+ stacktrace: Some(vec![Span {
+ byte_range: children[0].byte_range(),
+ ..span.clone()
+ }]),
+ code: "PA005".to_owned(),
+ })?,
+ }
+ }
+
+ "prefix" => {
+ debug_assert!(children.len() == 2);
+ let op = children[0].utf8_text(src).unwrap();
+ let op_span = Span {
+ byte_range: children[0].byte_range(),
+ ..span.clone()
+ };
+ let right = rec_codegen(&children[1], src, filename, targets)?;
+ format!("__bee_fn_apply(__bee_get_id(__bee_env, [\"ops\", \"{}\"], \"{op_span}\"), [{right}], \"{span}\")",
+ match op {
+ "!" => "not",
+ "-" => "unary_minus",
+ _ => unimplemented!(
+ "`{}' prefix operator handling is missing in `codegen.rs` implentation",
+ op
+ ),
+ })
+ }
+
+ "infix" => {
+ debug_assert!(children.len() == 3);
+ let left = rec_codegen(&children[0], src, filename, targets)?;
+ let op = children[1].utf8_text(src).unwrap();
+ let op_span = Span {
+ byte_range: children[1].byte_range(),
+ ..span.clone()
+ };
+ let right = rec_codegen(&children[2], src, filename, targets)?;
+ format!("__bee_fn_apply(__bee_get_id(__bee_env, [\"ops\", \"{}\"], \"{op_span}\"), [{left}, {right}], \"{span}\")",
+ match op {
+ "==" => "eq",
+ "!=" => "neq",
+ "/" => "div",
+ "*" => "mul",
+ "%" => "mod",
+ "+" => "add",
+ "-" => "sub",
+ "<" => "lt",
+ ">" => "gt",
+ "<=" => "lte",
+ ">=" => "gte",
+ "|" => "or",
+ "&" => "and",
+ "|>" => "pipe",
+ "<|" => "reverse_pipe",
+ ".." => "range",
+ _ => unimplemented!(
+ "`{}' infix operator handling is missing in `codegen.rs` implentation",
+ op
+ ),
+ })
+ }
+
+ _ => unimplemented!(
+ "`{}' token kind handling is missing in `codegen.rs` implentation",
+ kind
+ ),
+ })
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn is_valid_extension(path: &Path) -> bool {
+ if let Some(ext) = path.extension() {
+ ext == "bee"
+ } else {
+ false
+ }
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn is_valid_filename(path: &Path) -> bool {
+ !path.file_stem().unwrap().to_string_lossy().contains('.')
+ && !path.to_string_lossy().contains(':')
+ && !path.to_string_lossy().contains('[')
+ && !path.to_string_lossy().contains(']')
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn hint(keyword: &str) -> Option<String> {
+ match keyword {
+ "import" => Some(
+ "`import` take one string argument which is a path, e.g. `import \"my_module.bee\"`"
+ .to_owned(),
+ ),
+ _ => None,
+ }
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn strip_quotes(x: &str) -> String {
+ debug_assert!(x.starts_with('\"') && x.chars().nth(x.len() - 1).unwrap() == '"');
+ x[1..x.len() - 1].to_owned()
+}
+
+#[inline(always)]
+fn children_codegen(
+ children: Vec<tree_sitter::Node>,
+ src: &[u8],
+ filename: &Path,
+ targets: &BTreeSet<&str>,
+) -> Result<Vec<String>, Error> {
+ #[cfg(feature = "rayon")]
+ {
+ let nodes: Nodes = children.into();
+ return nodes
+ .par_iter()
+ .map(|x| rec_codegen(x.into(), src, filename, targets))
+ .collect::<Result<Vec<_>, _>>();
+ }
+ #[cfg(not(feature = "rayon"))]
+ return children
+ .iter()
+ .map(|x| rec_codegen(x, src, filename, targets))
+ .collect::<Result<Vec<_>, _>>();
+}
+
+/// TODO: write documentation...
+pub(crate) fn targets_codegen(targets: &BTreeSet<&str>) -> String {
+ let targets = targets
+ .iter()
+ .map(|x| format!("__bee_targets.{x} = true;"))
+ .collect::<Vec<String>>()
+ .join("\n");
+ format!(
+ "// TARGETS
+const __bee_targets = {{}};
+{targets}
+"
+ )
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn is_reserved_keywords(x: &str) -> bool {
+ matches!(
+ x,
+ "abstract"
+ | "__proto__"
+ | "arguments"
+ | "as"
+ | "async"
+ | "await"
+ | "boolean"
+ | "break"
+ | "byte"
+ | "case"
+ | "catch"
+ | "char"
+ | "class"
+ | "concrete"
+ | "const"
+ | "constructor"
+ | "continue"
+ | "debugger"
+ | "default"
+ | "delete"
+ | "do"
+ | "double"
+ | "else"
+ | "enum"
+ | "eval"
+ | "export"
+ | "extends"
+ | "false"
+ | "final"
+ | "finally"
+ | "float"
+ | "for"
+ | "from"
+ | "function"
+ | "get"
+ | "goto"
+ | "hasOwnProperty"
+ | "if"
+ | "implements"
+ | "import"
+ | "in"
+ | "instanceof"
+ | "int"
+ | "interface"
+ | "isPrototypeOf"
+ | "let"
+ | "long"
+ | "native"
+ | "new"
+ | "null"
+ | "of"
+ | "package"
+ | "private"
+ | "propertyIsEnumerable"
+ | "protected"
+ | "public"
+ | "return"
+ | "set"
+ | "short"
+ | "static"
+ | "super"
+ | "switch"
+ | "synchronized"
+ | "then"
+ | "this"
+ | "throw"
+ | "throws"
+ | "toLocaleString"
+ | "toString"
+ | "transient"
+ | "true"
+ | "try"
+ | "typeof"
+ | "valueOf"
+ | "var"
+ | "void"
+ | "volatile"
+ | "while"
+ | "with"
+ | "yield"
+ ) || (x.len() >= 5 && &x[..5] == "__bee")
+}
A => src/eval.rs +107 -0
@@ 0,0 1,107 @@
+use crate::build::Error;
+use crate::parser::Span;
+use log::debug;
+use regex::Regex;
+
+/// Wow, what the !@#$ is this?
+///
+/// You've guessed it right – this evaluates a variant of the codegen at
+/// compile-time, one that uses a different prelude. When `prelude.bee` is
+/// compiled with the `@abstract` target, it provides users with a function
+/// that doesn't produce any side effects. Instead, it offers the abstract,
+/// type-as-values, equivalent of the expected result.
+///
+/// E.g., the `randint` function returns the `Range` of possible values when
+/// the program is built with the `@abstract` target, rather than generating
+/// native code:
+/// ```ignore
+/// randint = min => max =>
+/// if @abstract Range min max
+/// else native "${min} + Math.floor(Math.random() * ${max})"
+/// ```
+/// This approach means that the _soundness_ of a program's typing is linked to
+/// the _soundness_ of the Bee standard library constructs. You can find more
+/// details about how this is implemented in the Prelude documentation.
+///
+/// However, there is a downside. By embedding `deno_core`, a large crate, as a
+/// dependency of our compiler, `bee` has become a self-contained binary of
+/// ~60Mb. So, what's the alternative? The solution could be to implement our
+/// own VM that directly interprets the AST: `eval(s: &S) -> Result<(), Error>`
+///
+/// Such a VM implementation could also be repurposed to build, for example, a
+/// REPL!
+pub fn eval(src: String) -> Result<(), Error> {
+ #[cfg(all(feature = "quickjs", feature = "deno"))]
+ return Err(compile_error!(
+ "cargo features `deno` and `quickjs` are mutually exclusive"
+ ));
+ #[cfg(all(not(feature = "quickjs"), not(feature = "deno")))]
+ todo!(); // FIXME: use an external program (set in BEE_RUNTIME env
+ // variable) to perform the evaluation?
+ #[cfg(all(not(feature = "quickjs"), feature = "deno"))]
+ {
+ let mut rt = deno_core::JsRuntime::new(deno_core::RuntimeOptions::default());
+ Ok(if let Err(err) = rt.execute_script("<usage>", src.into()) {
+ debug!("Deno error: {err}");
+ read_debug_symbols(&err.to_string())?
+ })
+ }
+ #[cfg(all(feature = "quickjs", not(feature = "deno")))]
+ {
+ let rt = rquickjs::Runtime::new().unwrap();
+ rt.set_max_stack_size(1024 * 1024);
+ let ctx = rquickjs::Context::full(&rt).unwrap();
+ ctx.with(|ctx| {
+ if let Err(rquickjs::Error::Exception) = ctx.eval::<(), _>(src) {
+ let err = ctx.catch().as_exception().unwrap().message().unwrap();
+ debug!("QuickJS error: {err}");
+ read_debug_symbols(&err)?
+ }
+ Ok(())
+ })
+ }
+}
+
+/// TODO: write documentation...
+#[inline(always)]
+pub fn read_debug_symbols(trace: &str) -> Result<(), Error> {
+ if trace == "stack overflow" {
+ // FIXME: use `__bee_stacktrace` to give user a more semantic error!
+ // ctx.globals().get::<_, rquickjs::Array>("__bee_stacktrace").unwrap();
+ return Err(Error {
+ help: None,
+ msg: "a stack overflow was encountered, it's likely caused by an infinite recursion"
+ .to_owned(),
+ code: "TY007".to_owned(),
+ stacktrace: None,
+ });
+ }
+ let pattern = Regex::new(r"(\[.+:\d+:\d+\])* ([A-Z]{2}\d{3}) (.+)").unwrap();
+ let cap = pattern.captures_iter(trace).next().unwrap();
+ debug_assert!(cap.len() == 4);
+ let mut spans = cap[1].split("][").collect::<Vec<&str>>();
+ let last = spans.len() - 1;
+ spans[0] = spans[0].strip_prefix('[').unwrap();
+ spans[last] = spans[last].strip_suffix(']').unwrap();
+ let stacktrace: Option<Vec<Span>> = Some(
+ (0..=last)
+ .map(|i| {
+ let pattern = Regex::new(r"(.+):(\d+):(\d+)").unwrap();
+ let cap = pattern.captures_iter(spans[i]).next().unwrap();
+ debug_assert!(cap.len() == 4);
+ Span {
+ byte_range: cap[2].parse().unwrap()..cap[3].parse().unwrap(),
+ filename: cap[1].into(),
+ }
+ })
+ .collect(),
+ );
+ let code = cap[2].to_owned();
+ let msg = cap[3].to_owned();
+ Err(Error {
+ help: None,
+ msg,
+ code,
+ stacktrace,
+ })
+}
A => src/lib.rs +25 -0
@@ 0,0 1,25 @@
+//! TODO: write documentation...
+//!
+//! FIXME: use `cargo-sync-readme` to turn "to-be-written" crate top doc comment
+//! into a proper `README.md`!
+//!
+//! MSRV 1.70.0
+
+#[macro_use]
+extern crate lazy_static;
+
+/// TODO: write documentation...
+pub mod build;
+/// TODO: write documentation...
+pub mod cache;
+/// TODO: write documentation...
+pub mod cli;
+/// TODO: write documentation...
+pub mod codegen;
+/// TODO: write documentation...
+pub mod eval;
+/// TODO: write documentation...
+pub mod parser;
+
+/// TODO: write documentation...
+pub const VERSION: &str = "0.0.1";
A => src/parser.rs +79 -0
@@ 0,0 1,79 @@
+use std::fmt::Display;
+use std::ops::Range;
+use std::path::PathBuf;
+
+// FIXME: use https://codeberg.org/xlambein/ts-typed-ast
+// include!(concat!(env!("OUT_DIR"), "/ast.rs"));
+
+/// TODO: write documentation...
+pub fn parse(src: &[u8]) -> tree_sitter::Tree {
+ let mut parser = tree_sitter::Parser::new();
+ parser
+ .set_language(tree_sitter_bee_lang::language())
+ .unwrap();
+ parser.parse(src, None).unwrap()
+}
+
+/// TODO: write documentation...
+#[derive(Debug, Clone)]
+pub struct Span {
+ /// TODO: write documentation...
+ pub byte_range: Range<usize>,
+ /// TODO: write documentation...
+ pub filename: PathBuf,
+}
+
+impl Display for Span {
+ #[inline(always)]
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ // FIXME: this Display could cause confusion, since we output the
+ // `byte_range` and not the `line:column` ...
+ write!(
+ f,
+ "[{}:{}:{}]",
+ self.filename.display(),
+ self.byte_range.start,
+ self.byte_range.end
+ )?;
+ Ok(())
+ }
+}
+
+// FIXME: this was fixed in the `master` branch of TreeSitter, so this will
+// soon no longer be needed :)
+
+#[cfg(feature = "rayon")]
+pub(crate) struct NodeWrapper<'a>(tree_sitter::Node<'a>);
+
+#[cfg(feature = "rayon")]
+unsafe impl<'a> Sync for NodeWrapper<'a> {}
+
+#[cfg(feature = "rayon")]
+pub(crate) struct Nodes<'a>(Vec<NodeWrapper<'a>>);
+
+#[cfg(feature = "rayon")]
+impl<'a> From<Vec<tree_sitter::Node<'a>>> for Nodes<'a> {
+ #[inline(always)]
+ fn from(nodes: Vec<tree_sitter::Node<'a>>) -> Self {
+ Self(nodes.into_iter().map(NodeWrapper).collect())
+ }
+}
+
+#[cfg(feature = "rayon")]
+impl<'a, 'b> From<&'b NodeWrapper<'a>> for &'b tree_sitter::Node<'a> {
+ #[inline(always)]
+ fn from(safe_node: &'b NodeWrapper<'a>) -> Self {
+ &safe_node.0
+ }
+}
+
+#[cfg(feature = "rayon")]
+impl<'a> rayon::iter::IntoParallelRefIterator<'a> for Nodes<'a> {
+ type Iter = rayon::slice::Iter<'a, NodeWrapper<'a>>;
+ type Item = &'a NodeWrapper<'a>;
+
+ #[inline(always)]
+ fn par_iter(&'a self) -> Self::Iter {
+ self.0.par_iter()
+ }
+}
A => src/prelude.bee +208 -0
@@ 0,0 1,208 @@
+{
+ // assert :: Bool -> ()
+ assert = x => if x {} else panic "assertion failed"
+ // FIXME: add an "assert?" runtime primitive
+
+ // FIXME: add an UNSAFE "require"?
+
+ // show :: Any -> String
+ show = x => native "__bee_debug_display(${x})" // FIXME: use in print ...
+
+ // print :: Any -> ()
+ print = x => if @abstract {} else { x = show x; native "console.log(${x})"; return {} }
+
+ console = { log = print }
+
+ // parse :: String -> Any
+ parse = str => native "JSON.parse(${str})"
+
+ // length :: Object -> Number
+ length = obj => native "${obj}.length"
+
+ // reverse :: Object -> Object
+ reverse = obj => native "Array.isArray(${obj}) ? ${obj}.reverse() : Array.from(${obj}).reverse().join('')"
+
+ maths = {
+ // pow :: Number -> Number -> Number
+ pow = base => exponent => native "Math.pow(${base}, ${exponent})"
+
+ // sqrt :: Number -> Number
+ sqrt = x => native "Math.sqrt(${x})"
+
+ // abs :: Number -> Number
+ abs = x => native "Math.abs(${x})"
+
+ // round :: Number -> Number
+ round = x => native "Math.round(${x})"
+
+ // floor :: Number -> Number
+ floor = x => native "Math.floor(${x})"
+
+ // ceil :: Number -> Number
+ ceil = x => native "Math.ceil(${x})"
+ }
+
+ array = {
+ // all :: Array a -> (a -> Bool) -> Bool
+ all = arr => predicate => native "Array.isArray(${arr}) && ${arr}.every(${predicate})"
+
+ // any :: Array a -> (a -> Bool) -> Bool
+ any = arr => predicate => native "Array.isArray(${arr}) && ${arr}.some(${predicate})"
+
+ // push :: Array a -> a -> Array a
+ push = arr => item => native "(() => { ${arr}.push(${item}); return ${arr}; })()"
+
+ // pop :: Array a -> a
+ pop = arr => native "(() => { return ${arr}.pop(); })()"
+
+ // sort :: Array a -> (a -> a -> Number) -> Array a
+ sort = arr => compareFunction => native "(() => { ${arr}.sort(${compareFunction}); return ${arr}; })()"
+
+ // filter :: Array a -> (a -> Bool) -> Array a
+ filter = arr => predicate => native "${arr}.filter(${predicate})"
+
+ // map :: Array a -> (a -> b) -> Array b
+ map = arr => mapper => native "${arr}.map(${mapper})"
+
+ // reduce :: Array a -> (b -> a -> b) -> b -> b
+ reduce = arr => reducer => initialValue => native "${arr}.reduce(${reducer}, ${initialValue})"
+
+ // forEach :: Array a -> (a -> ()) -> Array a
+ forEach = arr => action => native "(() => { ${arr}.forEach(${action}); return ${arr}; })()"
+
+ // find :: Array a -> (a -> Bool) -> a
+ find = arr => predicate => native "(${arr}.find(${predicate}) || null)"
+
+ // indexOf :: Array a -> a -> Number
+ indexOf = arr => item => native "${arr}.indexOf(${item})"
+
+ // slice :: Array a -> Number -> Number -> Array a
+ slice = arr => begin => end => native "${arr}.slice(${begin}, ${end})"
+
+ // reduceRight :: Array a -> (b -> a -> b) -> b -> b
+ reduceRight = arr => reducer => initialValue => native "${arr}.reduceRight(${reducer}, ${initialValue})"
+ }
+
+ string = {
+ // match :: String -> String -> Bool
+ match = str => pattern => native "${str}.match(${pattern})"
+
+ // chars :: String -> Array String
+ chars = str => native "Array.from(${str})"
+
+ // concat :: String -> String -> String
+ concat = str1 => str2 => native "${str1}.concat(${str2})"
+
+ // substring :: String -> Number -> Number -> String
+ substring = str => start => end => native "${str}.substring(${start}, ${end})"
+
+ // split :: String -> String -> Array String
+ split = str => delimiter => native "${str}.split(${delimiter})"
+
+ // trim :: String -> String
+ trim = str => native "${str}.trim()"
+
+ // toUpper :: String -> String
+ toUpper = str => native "${str}.toUpperCase()"
+
+ // toLower :: String -> String
+ toLower = str => native "${str}.toLowerCase()"
+
+ // indexOf :: String -> String -> Number
+ indexOf = str => searchStr => native "${str}.indexOf(${searchStr})"
+
+ // endsWith :: String -> String -> Bool
+ endsWith = str => searchStr => native "${str}.endsWith(${searchStr})"
+
+ // startsWith :: String -> String -> Bool
+ startsWith = str => searchStr => native "${str}.startsWith(${searchStr})"
+
+ // replace :: String -> String -> String -> String
+ replace = str => search => replacement => native "${str}.replace(${search}, ${replacement})"
+
+ // regexMatch :: String -> RegExp -> Array String
+ regexMatch = str => pattern => native "${str}.match(${pattern})"
+
+ // regexTest :: String -> RegExp -> Bool
+ regexTest = str => pattern => native "${pattern}.test(${str})"
+ }
+
+ object = {
+ // values :: Object -> Array Any
+ values = obj => native "Object.values(${obj})"
+
+ // keys :: Object -> Array String
+ keys = obj => native "Object.keys(${obj})"
+
+ // drop :: Object -> String -> Object
+ drop = obj => key => native "(() => { delete ${obj}[${key}]; return ${obj}; })()"
+
+ // merge :: Object -> Object -> Object
+ merge = obj1 => obj2 => native "Object.assign({}, ${obj1}, ${obj2})"
+ }
+
+ os = {
+ // UNSAFE readFile :: String -> String
+ readFile = path => encoding => native "require('fs').readFileSync(${path}, ${encoding})"
+
+ // UNSAFE writeFile :: String -> String -> ()
+ writeFile = path => data => native "require('fs').writeFileSync(${path}, ${data})"
+
+ // UNSAFE getenv :: String -> String
+ getenv = variable => native "process.env[${variable}]"
+
+ // UNSAFE setenv :: String -> String -> ()
+ setenv = variable => value => { native "(() => { process.env[${variable}] = ${value}; })()" }
+ }
+
+ // UNSAFE random :: () -> Number
+ random = _ => native "Math.random()"
+ // FIXME: add a randInt :: () -> BigInt
+
+ // UNSAFE getCurrentDate :: () -> String
+ getCurrentDate = _ => native "new Date().toISOString()"
+
+ // Explicit type-casting utils between Number (double / f64) and BigInt
+ toNumber = x => native "__bee_cast_to_number(${x})"
+ toBigInt = x => native "__bee_cast_to_bigint(${x})"
+
+ // Operators (infix and prefix) that can be overloaded by user :)
+ ops = {
+ // !x
+ not = x => native "__bee_op_not(${x})"
+ // -x
+ unary_minus = x => native "__bee_op_unary_minus(${x})"
+ // x == y
+ eq = x => y => native "__bee_op_eq(${x}, ${y})"
+ // x != y
+ neq = x => y => native "__bee_op_neq(${x}, ${y})"
+ // x / y
+ div = x => y => native "__bee_op_div(${x}, ${y})"
+ // x * y
+ mul = x => y => native "__bee_op_mul(${x}, ${y})"
+ // x % y
+ mod = x => y => native "__bee_op_mod(${x}, ${y})"
+ // x + y
+ add = x => y => native "__bee_op_add(${x}, ${y})"
+ // x - y
+ sub = x => y => native "__bee_op_sub(${x}, ${y})"
+ // x < y
+ lt = x => y => native "__bee_op_lt(${x}, ${y})"
+ // x > y
+ gt = x => y => native "__bee_op_gt(${x}, ${y})"
+ // x <= y
+ lte = x => y => native "__bee_op_lte(${x}, ${y})"
+ // x >= y
+ gte = x => y => native "__bee_op_gte(${x}, ${y})"
+ // x | y
+ or = x => y => native "__bee_op_or(${x}, ${y})"
+ // x & y
+ and = x => y => native "__bee_op_and(${x}, ${y})"
+ // x |> y
+ pipe = x => y => native "__bee_op_pipe(${x}, ${y})"
+ // x <| y
+ reverse_pipe = x => y => native "__bee_op_reverse_pipe(${x}, ${y})"
+ // x..y
+ range = start => end => native "__bee_op_range(${start}, ${end})"
+ }
+}
A => src/runtime.js +165 -0
@@ 0,0 1,165 @@
+const __bee_error = (__bee_error_code, __bee_msg, __bee_debug_symbol) => {
+ throw new Error(`${__bee_debug_symbol}${__bee_stacktrace.slice(0, 4).join("")} ${__bee_error_code} ${__bee_msg}`);
+};
+
+let __bee_env = {}; // FIXME: use a `Map()` instead?
+
+const __bee_env_tag = __bee_env => { return { __bee_env_cow: __bee_env }; };
+
+const __bee_env_untag = __bee_env => {
+ delete __bee_env.self;
+ delete __bee_env.__bee_env_cow;
+ return __bee_env;
+};
+
+// FIXME: add a an `unsafe` wrapper that check for undefined values!
+// __bee_env = (typeof __bee_env === 'undefined' ? {} : __bee_env);
+
+const __bee_env_error = (__bee_env, __bee_id, __bee_debug_symbol) =>
+ (typeof __bee_id === "string" && Array.isArray(__bee_env)
+ ? __bee_error("TY001", `you can't access the property \`${__bee_id}\` of the Array \`${__bee_debug_display(__bee_env)}\``, __bee_debug_symbol)
+ : (typeof __bee_id === "number" ? (Array.isArray(__bee_env)
+ // FIXME: add support for inverse index: [1 2 3].(-1) == 3 ?
+ ? (__bee_id >= __bee_env.length ? __bee_error("TY005", `out of bound access: try to access position \`${__bee_id}\` while \`${__bee_debug_display(__bee_env)}\` have a lenght of \`${__bee_env.length}\``, __bee_debug_symbol) : {})
+ : __bee_error("TY002", `you can't access the \`${__bee_id}\` element of the Object \`${__bee_debug_display(__bee_env)}\``, __bee_debug_symbol))
+ : __bee_error("TY003", `identifier \`${__bee_id}\` is not defined`, __bee_debug_symbol)));
+
+const __bee_get_id = (__bee_env, __bee_id, __bee_debug_symbol, __bee_in_self = false) => {
+ const __bee_get_name = (__bee_env, __bee_id, __bee_debug_symbol) =>
+ typeof __bee_env === "object" ? (__bee_id in __bee_env ? __bee_env[__bee_id]
+ : (/* !__bee_in_self && */ "__bee_env_cow" in __bee_env ? __bee_get_name(__bee_env.__bee_env_cow, __bee_id, __bee_debug_symbol)
+ : __bee_env_error(__bee_env, __bee_id, __bee_debug_symbol)))
+ : __bee_error("TY004", `\`${__bee_debug_display(__bee_env)}\` is neither an Array or Object, you can't use \`.\` operator on it`, __bee_debug_symbol);
+ const id = __bee_id.shift();
+ const value = __bee_get_name(__bee_env, id, __bee_debug_symbol);
+ return __bee_id.length ? __bee_get_id(value, __bee_id, __bee_debug_symbol, __bee_in_self || id == "self") : __bee_env_untag(value);
+};
+
+const __bee_env_copy = __bee_env => {
+ if (typeof __bee_env !== "object") { return __bee_env; }
+ if (Array.isArray(__bee_env)) { return __bee_env.map(x => __bee_env_copy(x)); }
+ const { self, __bee_env_cow, ...xs } = __bee_env;
+ const x = typeof __bee_env_cow === 'undefined' ? {} : __bee_env_copy(__bee_env_cow)
+ return {
+ ...x, ...Object.keys(xs).reduce((acc, key) => {
+ acc[key] = __bee_env_copy(xs[key]);
+ return acc;
+ }, {})
+ };
+};
+
+const __bee_stacktrace = [];
+
+const __bee_fn_apply = (__bee_ret, __bee_args, __bee_debug_symbol) => {
+ __bee_stacktrace.unshift(__bee_debug_symbol);
+ for (let i = 0; i < __bee_args.length; ++i) {
+ const __bee_arg = __bee_args[i]
+ __bee_ret = (typeof __bee_ret === "function" ? __bee_ret(__bee_arg)
+ : __bee_error("TY006", "function is called with too many arguments...", __bee_debug_symbol));
+ }
+ __bee_stacktrace.shift();
+ return __bee_ret;
+};
+
+const __bee_op_not = x => !x;
+
+const __bee_op_unary_minus = x => -x;
+
+const __bee_op_eq = (x, y) => x === y;
+
+const __bee_op_neq = (x, y) => x !== y;
+
+const __bee_op_add = (x, y) => {
+ __bee_check_types(x, y);
+ return x + y;
+};
+
+const __bee_op_sub = (x, y,) => {
+ __bee_check_types(x, y);
+ return x - y;
+};
+
+const __bee_op_mul = (x, y) => {
+ __bee_check_types(x, y);
+ return x * y;
+};
+
+const __bee_op_div = (x, y) => {
+ y == 0 ? __bee_error("TY009", `division by 0 is forbidden`, "") : {};
+ __bee_check_types(x, y);
+ return x / y;
+};
+
+const __bee_op_mod = (x, y) => {
+ __bee_check_types(x, y);
+ return x % y;
+};
+
+const __bee_check_types = (x, y) => {
+ // FIXME: check !isNan() and isFinite() ?
+ (typeof x == typeof y) ? {} : __bee_error("TY009", `can't mix ${typeof x} (${x}) and ${typeof y} (${y})`, "");
+ // FIXME: advice to use explicit type casting!
+};
+
+const __bee_op_lt = (x, y) => x < y;
+
+const __bee_op_gt = (x, y) => x > y;
+
+const __bee_op_lte = (x, y) => x <= y;
+
+const __bee_op_gte = (x, y) => x >= y;
+
+const __bee_op_and = (x, y) => x && y;
+
+const __bee_op_or = (x, y) => x || y;
+
+const __bee_op_pipe = (f, g) => typeof f == "function" ? x => g(f(x)) : g(f);
+
+const __bee_op_reverse_pipe = (f, g) => typeof f == "function" ? x => f(g(x)) : f(g);
+
+const __bee_op_range = (x, y) => {
+ // FIXME: should check that the conversion is safe ...
+ const start = __bee_cast_to_number(x);
+ const end = __bee_cast_to_number(y);
+ return Array.from({ length: end - start }, (_, i) => start + i);
+}
+
+const __bee_cast_to_number = x => Number.isSafeInteger(x) ? Number(x) : __bee_error("TY010", `${x} can't be safely convert to Number`, "");
+
+const __bee_cast_to_bigint = x => Number.isSafeInteger(x) ? BigInt(x) : __bee_error("TY011", `${x} can't be safely convert to BigInt`, "");
+
+const __bee_debug_display = (x, truncateLargeCollections = true) => {
+ const __bee_truncate_if_needed = (collection, truncate) => {
+ if (truncate && collection.length > 8) {
+ return [...collection.slice(0, 6), '...', collection[collection.length - 1]];
+ }
+ return collection;
+ };
+ if (typeof x === 'number') {
+ if (Number.isInteger(x)) {
+ return x + '.0';
+ } else {
+ return x.toString();
+ }
+ } else if (typeof x === 'bigint') {
+ return x.toString();
+ } else if (typeof x === 'string') {
+ return '"' + x + '"';
+ } else if (Array.isArray(x)) {
+ const arrayString = x.map(item => __bee_debug_display(item, truncateLargeCollections));
+ return '[' + __bee_truncate_if_needed(arrayString, truncateLargeCollections).join(', ') + ']';
+ } else if (typeof x === 'object' && x !== null) {
+ const objectString = Object.entries(x).map(([key, value]) => `${key} = ${__bee_debug_display(value, truncateLargeCollections)}`);
+ return '{' + __bee_truncate_if_needed(objectString, truncateLargeCollections).join('; ') + '}';
+ } else {
+ return x.toString();
+ }
+};
+
+// FIXME: write an alternative JS `.toString()` that turn any JS value into the
+// code that would be interpreted such as this value!
+
+// FIXME: __functor and __toString special attributes, e.g.:
+// let add = { __functor = self: x: x + self.x; };
+// inc = add // { x = 1; };
+// in inc 1
A => tree-sitter-bee-lang/.gitattributes +2 -0
@@ 0,0 1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto
A => tree-sitter-bee-lang/.gitignore +15 -0
@@ 0,0 1,15 @@
+# Build artifacts
+build/
+src/parser.c
+src/scanner.c
+
+# Dependency directories
+node_modules/
+
+# IDE/Editor specific files
+.vscode/
+.idea/
+
+# Operating System specific files
+.DS_Store
+Thumbs.db
A => tree-sitter-bee-lang/Cargo.toml +26 -0
@@ 0,0 1,26 @@
+[package]
+name = "tree-sitter-bee-lang"
+description = "Bee grammar for the tree-sitter parsing library"
+version = "0.1.0"
+keywords = ["incremental", "parsing", "bee"]
+categories = ["parsing", "text-editors"]
+edition = "2018"
+authors = ["Yvan Sraka <yvan@sraka.xyz>"]
+license = "GPLv2"
+
+build = "bindings/rust/build.rs"
+include = [
+ "bindings/rust/*",
+ "grammar.js",
+ "queries/*",
+ "src/*",
+]
+
+[lib]
+path = "bindings/rust/lib.rs"
+
+[dependencies]
+tree-sitter = "0.20"
+
+[build-dependencies]
+cc = "1.0"
A => tree-sitter-bee-lang/README.md +73 -0
@@ 0,0 1,73 @@
+## How to Set Up Bee Syntax Highlighting?
+
+This tutorial assumes that you have cloned this repository and that you are in the `tree-sitter` subfolder where this `README.md` resides.
+
+### VSCode
+
+Press `Ctrl` (`Cmd` on macOS) + `Shift` + `P`, then type "Developer: Install Extension from Location...", and select the `vscode-syntax-highlighting` folder.
+
+### Vim
+
+Copy the `bee.vim` file from this folder to `~/.vim/syntax/` (if you're using Neovim, the path is `~/.config/nvim/syntax/`).
+
+Edit (or create) the `filetype.vim` script, which should be in `~/.vim/` (or `~/.config/nvim/` for Neovim). It should contain the following lines:
+
+```vim
+if exists("did_load_filetypes")
+ finish
+endif
+
+augroup filetypedetect
+ au! BufRead,BufNewFile *.bee setfiletype bee
+augroup END
+```
+
+Ensure that your Vim is configured to allow custom syntax files and filetype detection. In your `~/.vimrc` (or `~/.config/nvim/init.vim` for Neovim), you should have syntax highlighting enabled with `syntax on` or `syntax enable`.
+
+### Emacs
+
+Copy the `bee-mode.el` file from this folder in a subdirectory of your Emacs configuration directory, e.g. `~/.emacs.d/bee/`.
+
+To automatically load this mode when opening `.bee` files, add the following lines to your Emacs configuration file (usually `~/.emacs` or `~/.emacs.d/init.el`):
+
+```elisp
+(add-to-list 'load-path "~/.emacs.d/bee/")
+(require 'bee-mode)
+```
+
+### Helix
+
+First, add the following to your `~/.config/helix/languages.toml` configuration file:
+
+```toml
+[[grammar]]
+name = "bee"
+
+[grammar.source]
+path = "/Users/yvan/bee-lang/tree-sitter" # Don't forget to change this line ;)
+
+[[language]]
+comment-token = "//"
+file-types = ["bee"]
+injection-regex = "bee"
+name = "bee"
+roots = ["main.bee"]
+scope = "source.bee"
+
+[language.indent]
+tab-width = 4
+unit = " "
+```
+
+Then run the following commands (from the folder containing the `grammar.js` file):
+
+```bash
+mkdir -p ~/.config/helix/runtime/{queries,grammars}
+ln -s "$(pwd)/queries" ~/.config/helix/runtime/queries/bee
+# /!\ Warning: re-run the next line after each change to grammar.js
+cc -shared src/parser.c -o ~/.config/helix/runtime/grammars/bee.so # (yes, .so and not .dylib, even on macOS...)
+```
+
+---
+
+If you still can't get syntax highlighting to work on your machine after following these instructions, please ask for help at discuss@bee-lang.org.
A => tree-sitter-bee-lang/bee-mode.el +51 -0
@@ 0,0 1,51 @@
+;;; bee-mode.el --- Syntax highlighting for Bee language
+
+; If you discover a way to improve Emacs syntax highlighting support by editing this file,
+; please share it with us at devel@bee-lang.org :)
+
+(defvar bee-font-lock-keywords
+ (let* (
+ ;; Define patterns for basic syntax categories.
+ (x-constants '("true" "false"))
+ (x-keywords '("if" "else" "import" "native" "return" "panic"))
+ (x-operators '("=" "=>" "==" "!=" "/" "*" "%" "+" "-" "<" ">" "<=" ">=" "|" "&" "|>" "<|" ".."))
+ (x-unary-operators '("!" "-"))
+ (x-spread-operator '("\\.\\.\\."))
+ (x-constants-regexp (regexp-opt x-constants 'words))
+ (x-keywords-regexp (regexp-opt x-keywords 'words))
+ (x-operators-regexp (regexp-opt x-operators))
+ (x-unary-operators-regexp (regexp-opt x-unary-operators))
+ (x-spread-operator-regexp (regexp-opt x-spread-operator))
+ (single-line-comment "//.*")
+ (multi-line-comment-start "/\\*")
+ (multi-line-comment-end "\\*/")
+ )
+ `(
+ (,x-constants-regexp . font-lock-constant-face)
+ (,x-keywords-regexp . font-lock-keyword-face)
+ (,x-operators-regexp . font-lock-operator-face)
+ (,x-unary-operators-regexp . font-lock-operator-face)
+ (,x-spread-operator-regexp . font-lock-operator-face)
+ ("@[a-zA-Z_][a-zA-Z0-9_]*" . font-lock-variable-name-face)
+ ("\\b[0-9]+\\b" . font-lock-number-face)
+ ("\".*?\"" . font-lock-string-face)
+ ("//.*" . font-lock-comment-face)
+ ("/\\*\\(.\\|\n\\)*?\\*/" . font-lock-comment-face)
+ (,single-line-comment . font-lock-comment-face)
+ (,multi-line-comment-start . font-lock-comment-face)
+ (,multi-line-comment-end . font-lock-comment-face)
+ ))
+ "Highlighting expressions for Bee mode")
+
+(define-derived-mode bee-mode prog-mode "Bee"
+ "Major mode for editing Bee language files."
+ (setq font-lock-defaults '((bee-font-lock-keywords)))
+ (modify-syntax-entry ?/ ". 124b" bee-mode-syntax-table)
+ (modify-syntax-entry ?* ". 23" bee-mode-syntax-table)
+ (modify-syntax-entry ?\n "> b" bee-mode-syntax-table))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.bee\\'" . bee-mode))
+
+(provide 'bee-mode)
+;;; bee-mode.el ends here
A => tree-sitter-bee-lang/bee.vim +50 -0
@@ 0,0 1,50 @@
+" Vim syntax file
+" Language: bee
+" File: bee.vim
+
+" If you discover a way to improve Vim syntax highlighting support by editing this file,
+" please share it with us at devel@bee-lang.org :)
+
+if exists("b:current_syntax")
+ finish
+endif
+
+syntax clear
+
+syntax keyword beeBoolean true false
+syntax keyword beeDirective @target
+syntax keyword beeControl panic if else
+syntax keyword beeConditional if else
+syntax keyword beeImport import
+syntax keyword beeSpecialFunction native
+syntax keyword beeReturn return
+
+syntax match beeOperator "\v[=!/\*\%+\-<>|&]+"
+syntax match beeUnaryOperator "\v[!\-]"
+syntax match beeSpreadOperator "\.\.\."
+syntax match beeDelimiter "[{}();\[\]]"
+syntax match beeNumber "\v\-?\d+(\.\d+)?([eE][\-+]?\d+)?"
+syntax match beeString /"[^"\\]*"/
+syntax match beeComment "//.*" contains=beeTodo
+syntax region beeComment start="/\*" end="\*/" contains=beeTodo
+" FIXME: recursive comments are not highlighted correctly ...
+
+syntax keyword beeTodo contained TODO FIXME XXX
+
+hi def link beeBoolean Boolean
+hi def link beeDirective Identifier
+hi def link beeControl Statement
+hi def link beeConditional Conditional
+hi def link beeImport Include
+hi def link beeSpecialFunction PreProc
+hi def link beeReturn Keyword
+hi def link beeOperator Operator
+hi def link beeUnaryOperator Operator
+hi def link beeSpreadOperator Operator
+hi def link beeDelimiter Delimiter
+hi def link beeNumber Number
+hi def link beeString String
+hi def link beeComment Comment
+hi def link beeTodo Todo
+
+let b:current_syntax = "bee"
A => tree-sitter-bee-lang/binding.gyp +19 -0
@@ 0,0 1,19 @@
+{
+ "targets": [
+ {
+ "target_name": "tree_sitter_bee_binding",
+ "include_dirs": [
+ "<!(node -e \"require('nan')\")",
+ "src"
+ ],
+ "sources": [
+ "bindings/node/binding.cc",
+ "src/parser.c",
+ # If your language uses an external scanner, add it here.
+ ],
+ "cflags_c": [
+ "-std=c99",
+ ]
+ }
+ ]
+}
A => tree-sitter-bee-lang/bindings/node/binding.cc +28 -0
@@ 0,0 1,28 @@
+#include "tree_sitter/parser.h"
+#include <node.h>
+#include "nan.h"
+
+using namespace v8;
+
+extern "C" TSLanguage * tree_sitter_bee();
+
+namespace {
+
+NAN_METHOD(New) {}
+
+void Init(Local<Object> exports, Local<Object> module) {
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
+ tpl->SetClassName(Nan::New("Language").ToLocalChecked());
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+
+ Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
+ Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
+ Nan::SetInternalFieldPointer(instance, 0, tree_sitter_bee());
+
+ Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("bee").ToLocalChecked());
+ Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
+}
+
+NODE_MODULE(tree_sitter_bee_binding, Init)
+
+} // namespace
A => tree-sitter-bee-lang/bindings/node/index.js +19 -0
@@ 0,0 1,19 @@
+try {
+ module.exports = require("../../build/Release/tree_sitter_bee_binding");
+} catch (error1) {
+ if (error1.code !== 'MODULE_NOT_FOUND') {
+ throw error1;
+ }
+ try {
+ module.exports = require("../../build/Debug/tree_sitter_bee_binding");
+ } catch (error2) {
+ if (error2.code !== 'MODULE_NOT_FOUND') {
+ throw error2;
+ }
+ throw error1
+ }
+}
+
+try {
+ module.exports.nodeTypeInfo = require("../../src/node-types.json");
+} catch (_) {}
A => tree-sitter-bee-lang/bindings/rust/build.rs +40 -0
@@ 0,0 1,40 @@
+fn main() {
+ let src_dir = std::path::Path::new("src");
+
+ let mut c_config = cc::Build::new();
+ c_config.include(&src_dir);
+ c_config
+ .flag_if_supported("-Wno-unused-parameter")
+ .flag_if_supported("-Wno-unused-but-set-variable")
+ .flag_if_supported("-Wno-trigraphs");
+ let parser_path = src_dir.join("parser.c");
+ c_config.file(&parser_path);
+
+ // If your language uses an external scanner written in C,
+ // then include this block of code:
+
+ /*
+ let scanner_path = src_dir.join("scanner.c");
+ c_config.file(&scanner_path);
+ println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
+ */
+
+ c_config.compile("parser");
+ println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
+
+ // If your language uses an external scanner written in C++,
+ // then include this block of code:
+
+ /*
+ let mut cpp_config = cc::Build::new();
+ cpp_config.cpp(true);
+ cpp_config.include(&src_dir);
+ cpp_config
+ .flag_if_supported("-Wno-unused-parameter")
+ .flag_if_supported("-Wno-unused-but-set-variable");
+ let scanner_path = src_dir.join("scanner.cc");
+ cpp_config.file(&scanner_path);
+ cpp_config.compile("scanner");
+ println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
+ */
+}
A => tree-sitter-bee-lang/bindings/rust/lib.rs +52 -0
@@ 0,0 1,52 @@
+//! This crate provides bee language support for the [tree-sitter][] parsing library.
+//!
+//! Typically, you will use the [language][language func] function to add this language to a
+//! tree-sitter [Parser][], and then use the parser to parse some code:
+//!
+//! ```
+//! let code = "";
+//! let mut parser = tree_sitter::Parser::new();
+//! parser.set_language(tree_sitter_bee::language()).expect("Error loading bee grammar");
+//! let tree = parser.parse(code, None).unwrap();
+//! ```
+//!
+//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
+//! [language func]: fn.language.html
+//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
+//! [tree-sitter]: https://tree-sitter.github.io/
+
+use tree_sitter::Language;
+
+extern "C" {
+ fn tree_sitter_bee() -> Language;
+}
+
+/// Get the tree-sitter [Language][] for this grammar.
+///
+/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
+pub fn language() -> Language {
+ unsafe { tree_sitter_bee() }
+}
+
+/// The content of the [`node-types.json`][] file for this grammar.
+///
+/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
+pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
+
+// Uncomment these to include any queries that this grammar contains
+
+// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
+// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
+// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
+// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn test_can_load_grammar() {
+ let mut parser = tree_sitter::Parser::new();
+ parser
+ .set_language(super::language())
+ .expect("Error loading bee language");
+ }
+}
A => tree-sitter-bee-lang/grammar.js +71 -0
@@ 0,0 1,71 @@
+// This grammar have by design, no conflicts between rules and no need for
+// precedence rules, instead it force the use of parenthesis on any ambiguity
+// this is a feature!
+
+const list = (value, delimiter) => optional(seq(value, repeat(seq(delimiter, value)), optional(delimiter)));
+
+module.exports = grammar({
+ name: 'bee',
+ extras: $ => [/\s/, $.inline_comment, $.block_comment],
+ // FIXME: https://github.com/tree-sitter/tree-sitter/pull/1635
+ // reserved: _ => ['true', 'false', 'if', 'else', 'return', 'native', 'import'],
+ word: $ => $.name,
+ rules: {
+ source_file: $ => $.expr,
+ expr: $ => choice($.fn, $.statement, $.value, $.prefix, $.infix, seq('(', $.expr, ')')),
+ value: $ => choice($.array, $.bigint, $.bool, $.id, $.f64, $.string, $.target),
+ statement: $ => choice($.do, $.if_then_else, $.import_, $.native_, $.panic_, $.let, $.apply),
+ apply: $ => seq($.arg, repeat1($.arg)),
+ arg: $ => choice($.value, $.do, seq('(', $.expr, ')')),
+ array: $ => seq('[', list($.expr, ','), ']'),
+ delimiter: $ => choice(';', '\n'),
+ field: $ => choice($.return_, $.statement, $.name_alias, $.spread),
+ do: $ => seq('{', list($.field, $.delimiter), '}'),
+ if_then_else: $ => seq('if', $.arg, $.expr, seq('else', $.expr)),
+ let: $ => seq($.name, '=', $.expr), // FIXME: let use $.id instead of $.name?
+ fn: $ => seq($.name, '=>', $.expr),
+ spread: $ => seq("...", $.id), // FIXME: spread arbitrary $.expr? spread in $.array?
+ return_: $ => seq('return', $.expr),
+ panic_: $ => seq('panic', $.string),
+ native_: $ => seq('native', $.string),
+ import_: $ => seq('import', $.string),
+ id: $ => seq(choice($.name, $.placeholder), repeat(seq('.', choice($.name, $.nth, $.placeholder)))),
+ nth: _ => /-?\d+/,
+ placeholder: $ => seq('$', '{', $.expr, '}'),
+ bool: _ => choice('true', 'false'),
+ target: _ => /@[a-zA-Z_][a-zA-Z0-9_]*/,
+ name_alias: $ => $.name,
+ name: _ => /[a-zA-Z_][a-zA-Z0-9_]*/,
+ bigint: _ => /-?\d+([eE]+?\d+)?/,
+ f64: _ => /-?\d+(\.\d+)?([eE][-+]?\d+)?/,
+ string: _ => /"([^"\\]|\\.)*"/,
+ inline_comment: _ => seq('//', /.*/),
+ block_comment: $ => seq('/*', repeat(choice(/[^*]/, /\*[^/]/, $.block_comment)), '*/'),
+ prefix: $ => choice(
+ ...[
+ '!', '-'
+ ].map(operator =>
+ seq(
+ operator,
+ $.arg
+ )
+ )
+ ),
+ infix: $ => choice(
+ ...[
+ '==', '!=', '/', '*', '%', '+', '-', '<', '>', '<=', '>=', '|', '&', '|>', '<|', '..'
+ ].map(operator =>
+ seq(
+ $.arg,
+ operator,
+ $.arg
+ )
+ )
+ ),
+ // FIXME: `.` operator should be callable directly on array or object inline declaration ...
+ // FIXME: add `async` and `await` support ... in grammar? in prelude?
+ }
+});
+
+// FIXME: open a PR to add syntax highlighting support to Zed editor ...
+// https://github.com/zed-industries/zed/tree/main/crates/zed/src/languages
A => tree-sitter-bee-lang/package-lock.json +32 -0
@@ 0,0 1,32 @@
+{
+ "name": "tree-sitter-bee-lang",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "tree-sitter-bee-lang",
+ "version": "0.1.0",
+ "license": "ISC",
+ "dependencies": {
+ "nan": "^2.18.0"
+ },
+ "devDependencies": {
+ "tree-sitter-cli": "^0.20.8"
+ }
+ },
+ "node_modules/nan": {
+ "version": "2.18.0",
+ "license": "MIT"
+ },
+ "node_modules/tree-sitter-cli": {
+ "version": "0.20.8",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "tree-sitter": "cli.js"
+ }
+ }
+ }
+}
A => tree-sitter-bee-lang/package.json +22 -0
@@ 0,0 1,22 @@
+{
+ "name": "tree-sitter-bee-lang",
+ "version": "0.1.0",
+ "description": "Bee grammar for the tree-sitter parsing library",
+ "main": "bindings/node",
+ "author": "Yvan Sraka <yvan@sraka.xyz>",
+ "license": "ISC",
+ "dependencies": {
+ "nan": "^2.18.0"
+ },
+ "devDependencies": {
+ "tree-sitter-cli": "^0.20.8"
+ },
+ "tree-sitter": [
+ {
+ "scope": "source.bee",
+ "file-types": [
+ "bee"
+ ]
+ }
+ ]
+}
A => tree-sitter-bee-lang/queries/highlights.scm +16 -0
@@ 0,0 1,16 @@
+(bool) @constant.builtin.boolean
+(id) @variable.other
+(string) @string
+(target) @keyword.directive
+[";"] @punctuation.delimiter
+["!" "-"] @operator.unary
+["..."] @operator.spread
+["{" "(" "[" "]" ")" "}"] @punctuation.bracket
+["=" "=>" "==" "!=" "/" "*" "%" "+" "-" "<" ">" "<=" ">=" "|" "&" "|>" "<|" ".."] @operator
+["panic"] @keyword.control
+["if" "else"] @keyword.control.conditional
+["import"] @keyword.control.import
+["native"] @function.special
+["return"] @keyword.control.return
+[(bigint) (f64)] @number
+[(inline_comment) (block_comment)] @comment
A => tree-sitter-bee-lang/queries/injections.scm +4 -0
@@ 0,0 1,4 @@
+([(inline_comment)] @injection.content
+ (#set! injection.language "inline_comment"))
+([(block_comment)] @injection.content
+ (#set! injection.language "block_comment"))
A => tree-sitter-bee-lang/queries/locals.scm +5 -0
@@ 0,0 1,5 @@
+(do (field) @scope)
+(let (name) @variable)
+(fn (name) @parameter)
+(block_comment) @comment
+(inline_comment) @comment
A => tree-sitter-bee-lang/queries/tags.scm +5 -0
@@ 0,0 1,5 @@
+(do) @foldable
+(block_comment) @foldable
+(array) @foldable
+(if_then_else) @foldable
+(fn) @foldable
A => tree-sitter-bee-lang/src/grammar.json +926 -0
@@ 0,0 1,926 @@
+{
+ "name": "bee",
+ "word": "name",
+ "rules": {
+ "source_file": {
+ "type": "SYMBOL",
+ "name": "expr"
+ },
+ "expr": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "fn"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "statement"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "value"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "prefix"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "infix"
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "("
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ },
+ {
+ "type": "STRING",
+ "value": ")"
+ }
+ ]
+ }
+ ]
+ },
+ "value": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "array"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "bigint"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "bool"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "id"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "f64"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "string"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "target"
+ }
+ ]
+ },
+ "statement": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "do"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "if_then_else"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "import_"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "native_"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "panic_"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "let"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "apply"
+ }
+ ]
+ },
+ "apply": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "REPEAT1",
+ "content": {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ }
+ ]
+ },
+ "arg": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "value"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "do"
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "("
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ },
+ {
+ "type": "STRING",
+ "value": ")"
+ }
+ ]
+ }
+ ]
+ },
+ "array": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "["
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ },
+ {
+ "type": "REPEAT",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": ","
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ }
+ ]
+ }
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "STRING",
+ "value": ","
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "]"
+ }
+ ]
+ },
+ "delimiter": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "STRING",
+ "value": ";"
+ },
+ {
+ "type": "STRING",
+ "value": "\n"
+ }
+ ]
+ },
+ "field": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "return_"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "statement"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "name_alias"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "spread"
+ }
+ ]
+ },
+ "do": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "{"
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "field"
+ },
+ {
+ "type": "REPEAT",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "delimiter"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "field"
+ }
+ ]
+ }
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "delimiter"
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "BLANK"
+ }
+ ]
+ },
+ {
+ "type": "STRING",
+ "value": "}"
+ }
+ ]
+ },
+ "if_then_else": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "if"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "else"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ }
+ ]
+ }
+ ]
+ },
+ "let": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "name"
+ },
+ {
+ "type": "STRING",
+ "value": "="
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ }
+ ]
+ },
+ "fn": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "name"
+ },
+ {
+ "type": "STRING",
+ "value": "=>"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ }
+ ]
+ },
+ "spread": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "..."
+ },
+ {
+ "type": "SYMBOL",
+ "name": "id"
+ }
+ ]
+ },
+ "return_": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "return"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ }
+ ]
+ },
+ "panic_": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "panic"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "string"
+ }
+ ]
+ },
+ "native_": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "native"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "string"
+ }
+ ]
+ },
+ "import_": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "import"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "string"
+ }
+ ]
+ },
+ "id": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "name"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "placeholder"
+ }
+ ]
+ },
+ {
+ "type": "REPEAT",
+ "content": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "."
+ },
+ {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "name"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "nth"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "placeholder"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "nth": {
+ "type": "PATTERN",
+ "value": "-?\\d+"
+ },
+ "placeholder": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "$"
+ },
+ {
+ "type": "STRING",
+ "value": "{"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "expr"
+ },
+ {
+ "type": "STRING",
+ "value": "}"
+ }
+ ]
+ },
+ "bool": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "true"
+ },
+ {
+ "type": "STRING",
+ "value": "false"
+ }
+ ]
+ },
+ "target": {
+ "type": "PATTERN",
+ "value": "@[a-zA-Z_][a-zA-Z0-9_]*"
+ },
+ "name_alias": {
+ "type": "SYMBOL",
+ "name": "name"
+ },
+ "name": {
+ "type": "PATTERN",
+ "value": "[a-zA-Z_][a-zA-Z0-9_]*"
+ },
+ "bigint": {
+ "type": "PATTERN",
+ "value": "-?\\d+([eE]+?\\d+)?"
+ },
+ "f64": {
+ "type": "PATTERN",
+ "value": "-?\\d+(\\.\\d+)?([eE][-+]?\\d+)?"
+ },
+ "string": {
+ "type": "PATTERN",
+ "value": "\"([^\"\\\\]|\\\\.)*\""
+ },
+ "inline_comment": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "//"
+ },
+ {
+ "type": "PATTERN",
+ "value": ".*"
+ }
+ ]
+ },
+ "block_comment": {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "/*"
+ },
+ {
+ "type": "REPEAT",
+ "content": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "PATTERN",
+ "value": "[^*]"
+ },
+ {
+ "type": "PATTERN",
+ "value": "\\*[^/]"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "block_comment"
+ }
+ ]
+ }
+ },
+ {
+ "type": "STRING",
+ "value": "*/"
+ }
+ ]
+ },
+ "prefix": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "!"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "STRING",
+ "value": "-"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ }
+ ]
+ },
+ "infix": {
+ "type": "CHOICE",
+ "members": [
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "=="
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "!="
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "/"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "*"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "%"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "+"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "-"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "<"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": ">"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "<="
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": ">="
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "|"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "&"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "|>"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": "<|"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ },
+ {
+ "type": "SEQ",
+ "members": [
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ },
+ {
+ "type": "STRING",
+ "value": ".."
+ },
+ {
+ "type": "SYMBOL",
+ "name": "arg"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "extras": [
+ {
+ "type": "PATTERN",
+ "value": "\\s"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "inline_comment"
+ },
+ {
+ "type": "SYMBOL",
+ "name": "block_comment"
+ }
+ ],
+ "conflicts": [],
+ "precedences": [],
+ "externals": [],
+ "inline": [],
+ "supertypes": []
+}
+
A => tree-sitter-bee-lang/src/node-types.json +666 -0
@@ 0,0 1,666 @@
+[
+ {
+ "type": "apply",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "arg",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "arg",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "do",
+ "named": true
+ },
+ {
+ "type": "expr",
+ "named": true
+ },
+ {
+ "type": "value",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "array",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": false,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "block_comment",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": false,
+ "types": [
+ {
+ "type": "block_comment",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "bool",
+ "named": true,
+ "fields": {}
+ },
+ {
+ "type": "delimiter",
+ "named": true,
+ "fields": {}
+ },
+ {
+ "type": "do",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": false,
+ "types": [
+ {
+ "type": "delimiter",
+ "named": true
+ },
+ {
+ "type": "field",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "expr",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ },
+ {
+ "type": "fn",
+ "named": true
+ },
+ {
+ "type": "infix",
+ "named": true
+ },
+ {
+ "type": "prefix",
+ "named": true
+ },
+ {
+ "type": "statement",
+ "named": true
+ },
+ {
+ "type": "value",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "field",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "name_alias",
+ "named": true
+ },
+ {
+ "type": "return_",
+ "named": true
+ },
+ {
+ "type": "spread",
+ "named": true
+ },
+ {
+ "type": "statement",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "fn",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ },
+ {
+ "type": "name",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "id",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "name",
+ "named": true
+ },
+ {
+ "type": "nth",
+ "named": true
+ },
+ {
+ "type": "placeholder",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "if_then_else",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "arg",
+ "named": true
+ },
+ {
+ "type": "expr",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "import_",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "string",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "infix",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "arg",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "inline_comment",
+ "named": true,
+ "fields": {}
+ },
+ {
+ "type": "let",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": true,
+ "required": true,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ },
+ {
+ "type": "name",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "name_alias",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "name",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "native_",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "string",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "panic_",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "string",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "placeholder",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "prefix",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "arg",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "return_",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "source_file",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "expr",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "spread",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "id",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "statement",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "apply",
+ "named": true
+ },
+ {
+ "type": "do",
+ "named": true
+ },
+ {
+ "type": "if_then_else",
+ "named": true
+ },
+ {
+ "type": "import_",
+ "named": true
+ },
+ {
+ "type": "let",
+ "named": true
+ },
+ {
+ "type": "native_",
+ "named": true
+ },
+ {
+ "type": "panic_",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "value",
+ "named": true,
+ "fields": {},
+ "children": {
+ "multiple": false,
+ "required": true,
+ "types": [
+ {
+ "type": "array",
+ "named": true
+ },
+ {
+ "type": "bigint",
+ "named": true
+ },
+ {
+ "type": "bool",
+ "named": true
+ },
+ {
+ "type": "f64",
+ "named": true
+ },
+ {
+ "type": "id",
+ "named": true
+ },
+ {
+ "type": "string",
+ "named": true
+ },
+ {
+ "type": "target",
+ "named": true
+ }
+ ]
+ }
+ },
+ {
+ "type": "\n",
+ "named": false
+ },
+ {
+ "type": "!",
+ "named": false
+ },
+ {
+ "type": "!=",
+ "named": false
+ },
+ {
+ "type": "$",
+ "named": false
+ },
+ {
+ "type": "%",
+ "named": false
+ },
+ {
+ "type": "&",
+ "named": false
+ },
+ {
+ "type": "(",
+ "named": false
+ },
+ {
+ "type": ")",
+ "named": false
+ },
+ {
+ "type": "*",
+ "named": false
+ },
+ {
+ "type": "*/",
+ "named": false
+ },
+ {
+ "type": "+",
+ "named": false
+ },
+ {
+ "type": ",",
+ "named": false
+ },
+ {
+ "type": "-",
+ "named": false
+ },
+ {
+ "type": ".",
+ "named": false
+ },
+ {
+ "type": "..",
+ "named": false
+ },
+ {
+ "type": "...",
+ "named": false
+ },
+ {
+ "type": "/",
+ "named": false
+ },
+ {
+ "type": "/*",
+ "named": false
+ },
+ {
+ "type": "//",
+ "named": false
+ },
+ {
+ "type": ";",
+ "named": false
+ },
+ {
+ "type": "<",
+ "named": false
+ },
+ {
+ "type": "<=",
+ "named": false
+ },
+ {
+ "type": "<|",
+ "named": false
+ },
+ {
+ "type": "=",
+ "named": false
+ },
+ {
+ "type": "==",
+ "named": false
+ },
+ {
+ "type": "=>",
+ "named": false
+ },
+ {
+ "type": ">",
+ "named": false
+ },
+ {
+ "type": ">=",
+ "named": false
+ },
+ {
+ "type": "[",
+ "named": false
+ },
+ {
+ "type": "]",
+ "named": false
+ },
+ {
+ "type": "bigint",
+ "named": true
+ },
+ {
+ "type": "else",
+ "named": false
+ },
+ {
+ "type": "f64",
+ "named": true
+ },
+ {
+ "type": "false",
+ "named": false
+ },
+ {
+ "type": "if",
+ "named": false
+ },
+ {
+ "type": "import",
+ "named": false
+ },
+ {
+ "type": "name",
+ "named": true
+ },
+ {
+ "type": "native",
+ "named": false
+ },
+ {
+ "type": "nth",
+ "named": true
+ },
+ {
+ "type": "panic",
+ "named": false
+ },
+ {
+ "type": "return",
+ "named": false
+ },
+ {
+ "type": "string",
+ "named": true
+ },
+ {
+ "type": "target",
+ "named": true
+ },
+ {
+ "type": "true",
+ "named": false
+ },
+ {
+ "type": "{",
+ "named": false
+ },
+ {
+ "type": "|",
+ "named": false
+ },
+ {
+ "type": "|>",
+ "named": false
+ },
+ {
+ "type": "}",
+ "named": false
+ }
+]
No newline at end of file
A => tree-sitter-bee-lang/src/tree_sitter/parser.h +224 -0
@@ 0,0 1,224 @@
+#ifndef TREE_SITTER_PARSER_H_
+#define TREE_SITTER_PARSER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define ts_builtin_sym_error ((TSSymbol)-1)
+#define ts_builtin_sym_end 0
+#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
+
+typedef uint16_t TSStateId;
+
+#ifndef TREE_SITTER_API_H_
+typedef uint16_t TSSymbol;
+typedef uint16_t TSFieldId;
+typedef struct TSLanguage TSLanguage;
+#endif
+
+typedef struct {
+ TSFieldId field_id;
+ uint8_t child_index;
+ bool inherited;
+} TSFieldMapEntry;
+
+typedef struct {
+ uint16_t index;
+ uint16_t length;
+} TSFieldMapSlice;
+
+typedef struct {
+ bool visible;
+ bool named;
+ bool supertype;
+} TSSymbolMetadata;
+
+typedef struct TSLexer TSLexer;
+
+struct TSLexer {
+ int32_t lookahead;
+ TSSymbol result_symbol;
+ void (*advance)(TSLexer *, bool);
+ void (*mark_end)(TSLexer *);
+ uint32_t (*get_column)(TSLexer *);
+ bool (*is_at_included_range_start)(const TSLexer *);
+ bool (*eof)(const TSLexer *);
+};
+
+typedef enum {
+ TSParseActionTypeShift,
+ TSParseActionTypeReduce,
+ TSParseActionTypeAccept,
+ TSParseActionTypeRecover,
+} TSParseActionType;
+
+typedef union {
+ struct {
+ uint8_t type;
+ TSStateId state;
+ bool extra;
+ bool repetition;
+ } shift;
+ struct {
+ uint8_t type;
+ uint8_t child_count;
+ TSSymbol symbol;
+ int16_t dynamic_precedence;
+ uint16_t production_id;
+ } reduce;
+ uint8_t type;
+} TSParseAction;
+
+typedef struct {
+ uint16_t lex_state;
+ uint16_t external_lex_state;
+} TSLexMode;
+
+typedef union {
+ TSParseAction action;
+ struct {
+ uint8_t count;
+ bool reusable;
+ } entry;
+} TSParseActionEntry;
+
+struct TSLanguage {
+ uint32_t version;
+ uint32_t symbol_count;
+ uint32_t alias_count;
+ uint32_t token_count;
+ uint32_t external_token_count;
+ uint32_t state_count;
+ uint32_t large_state_count;
+ uint32_t production_id_count;
+ uint32_t field_count;
+ uint16_t max_alias_sequence_length;
+ const uint16_t *parse_table;
+ const uint16_t *small_parse_table;
+ const uint32_t *small_parse_table_map;
+ const TSParseActionEntry *parse_actions;
+ const char * const *symbol_names;
+ const char * const *field_names;
+ const TSFieldMapSlice *field_map_slices;
+ const TSFieldMapEntry *field_map_entries;
+ const TSSymbolMetadata *symbol_metadata;
+ const TSSymbol *public_symbol_map;
+ const uint16_t *alias_map;
+ const TSSymbol *alias_sequences;
+ const TSLexMode *lex_modes;
+ bool (*lex_fn)(TSLexer *, TSStateId);
+ bool (*keyword_lex_fn)(TSLexer *, TSStateId);
+ TSSymbol keyword_capture_token;
+ struct {
+ const bool *states;
+ const TSSymbol *symbol_map;
+ void *(*create)(void);
+ void (*destroy)(void *);
+ bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
+ unsigned (*serialize)(void *, char *);
+ void (*deserialize)(void *, const char *, unsigned);
+ } external_scanner;
+ const TSStateId *primary_state_ids;
+};
+
+/*
+ * Lexer Macros
+ */
+
+#define START_LEXER() \
+ bool result = false; \
+ bool skip = false; \
+ bool eof = false; \
+ int32_t lookahead; \
+ goto start; \
+ next_state: \
+ lexer->advance(lexer, skip); \
+ start: \
+ skip = false; \
+ lookahead = lexer->lookahead;
+
+#define ADVANCE(state_value) \
+ { \
+ state = state_value; \
+ goto next_state; \
+ }
+
+#define SKIP(state_value) \
+ { \
+ skip = true; \
+ state = state_value; \
+ goto next_state; \
+ }
+
+#define ACCEPT_TOKEN(symbol_value) \
+ result = true; \
+ lexer->result_symbol = symbol_value; \
+ lexer->mark_end(lexer);
+
+#define END_STATE() return result;
+
+/*
+ * Parse Table Macros
+ */
+
+#define SMALL_STATE(id) id - LARGE_STATE_COUNT
+
+#define STATE(id) id
+
+#define ACTIONS(id) id
+
+#define SHIFT(state_value) \
+ {{ \
+ .shift = { \
+ .type = TSParseActionTypeShift, \
+ .state = state_value \
+ } \
+ }}
+
+#define SHIFT_REPEAT(state_value) \
+ {{ \
+ .shift = { \
+ .type = TSParseActionTypeShift, \
+ .state = state_value, \
+ .repetition = true \
+ } \
+ }}
+
+#define SHIFT_EXTRA() \
+ {{ \
+ .shift = { \
+ .type = TSParseActionTypeShift, \
+ .extra = true \
+ } \
+ }}
+
+#define REDUCE(symbol_val, child_count_val, ...) \
+ {{ \
+ .reduce = { \
+ .type = TSParseActionTypeReduce, \
+ .symbol = symbol_val, \
+ .child_count = child_count_val, \
+ __VA_ARGS__ \
+ }, \
+ }}
+
+#define RECOVER() \
+ {{ \
+ .type = TSParseActionTypeRecover \
+ }}
+
+#define ACCEPT_INPUT() \
+ {{ \
+ .type = TSParseActionTypeAccept \
+ }}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TREE_SITTER_PARSER_H_
A => tree-sitter-bee-lang/vscode-syntax-highlighting/.gitattributes +2 -0
@@ 0,0 1,2 @@
+# Set default behavior to automatically normalize line endings.
+* text=auto
A => tree-sitter-bee-lang/vscode-syntax-highlighting/.gitignore +2 -0
@@ 0,0 1,2 @@
+node_modules
+*.vsix
No newline at end of file
A => tree-sitter-bee-lang/vscode-syntax-highlighting/.vscodeignore +4 -0
@@ 0,0 1,4 @@
+.vscode/**
+.vscode-test/**
+.gitignore
+vsc-extension-quickstart.md
A => tree-sitter-bee-lang/vscode-syntax-highlighting/language-configuration.json +28 -0
@@ 0,0 1,28 @@
+{
+ // If you discover a way to improve VSCode syntax highlighting support by editing this file (or syntaxes/bee.tmLanguage.json),
+ // please share it with us at devel@bee-lang.org :)
+ "comments": {
+ "lineComment": "//",
+ "blockComment": ["/*", "*/"]
+ },
+ // symbols used as brackets
+ "brackets": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"]
+ ],
+ // symbols that are auto closed when typing
+ "autoClosingPairs": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["\"", "\""],
+ ],
+ // symbols that can be used to surround a selection
+ "surroundingPairs": [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["\"", "\""],
+ ]
+}
A => tree-sitter-bee-lang/vscode-syntax-highlighting/package.json +25 -0
@@ 0,0 1,25 @@
+{
+ "name": "bee-syntax-highlighting",
+ "displayName": "Bee Syntax Highlighting",
+ "description": "Syntax highlighting for the Bee programming language",
+ "version": "0.0.1",
+ "engines": {
+ "vscode": "^1.85.0"
+ },
+ "categories": [
+ "Programming Languages"
+ ],
+ "contributes": {
+ "languages": [{
+ "id": "bee",
+ "aliases": ["Bee", "bee"],
+ "extensions": [".bee"],
+ "configuration": "./language-configuration.json"
+ }],
+ "grammars": [{
+ "language": "bee",
+ "scopeName": "source.bee",
+ "path": "./syntaxes/bee.tmLanguage.json"
+ }]
+ }
+}
A => tree-sitter-bee-lang/vscode-syntax-highlighting/syntaxes/bee.tmLanguage.json +89 -0
@@ 0,0 1,89 @@
+{
+ "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+ "name": "Bee",
+ "patterns": [
+ {
+ "include": "#keywords"
+ },
+ {
+ "include": "#strings"
+ },
+ {
+ "include": "#comments"
+ },
+ {
+ "include": "#operators"
+ },
+ {
+ "include": "#identifiers"
+ }
+ ],
+ "repository": {
+ "keywords": {
+ "patterns": [{
+ "name": "keyword.control.bee",
+ "match": "\\b(if|else|import|return|native|panic)\\b"
+ }]
+ },
+ "strings": {
+ "name": "string.quoted.double.bee",
+ "begin": "\"",
+ "end": "\"",
+ "patterns": [
+ {
+ "name": "constant.character.escape.bee",
+ "match": "\\\\."
+ },
+ {
+ "name": "variable.string.interpolated.bee",
+ "begin": "\\$\\{",
+ "end": "\\}",
+ "patterns": [
+ {
+ "include": "#variables"
+ }
+ ]
+ }
+ ]
+ },
+ "variables": {
+ "patterns": [
+ {
+ "name": "variable.name.bee",
+ "match": "[a-zA-Z_][a-zA-Z0-9_]*"
+ }
+ ]
+ },
+ "comments": {
+ "patterns": [
+ {
+ "name": "comment.line.double-slash.bee",
+ "match": "//.*"
+ },
+ {
+ "begin": "/\\*",
+ "end": "\\*/",
+ "name": "comment.block.bee",
+ "patterns": [
+ {
+ "include": "#comments"
+ }
+ ]
+ }
+ ]
+ },
+ "operators": {
+ "patterns": [
+ {
+ "name": "keyword.operator.arrow.bee",
+ "match": "=>"
+ },
+ {
+ "name": "keyword.operator.assignment.bee",
+ "match": "="
+ }
+ ]
+ }
+ },
+ "scopeName": "source.bee"
+}
A => webpack-loader/index.js +11 -0
@@ 0,0 1,11 @@
+const execSync = require('child_process').execSync;
+
+module.exports = function(_source) {
+ const callback = this.async();
+ try {
+ const output = execSync(`bee build < ${this.resourcePath}`);
+ callback(null, output.toString());
+ } catch (error) {
+ callback(error);
+ }
+};
A => webpack-loader/package-lock.json +13 -0
@@ 0,0 1,13 @@
+{
+ "name": "bee-webpack-loader",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "bee-webpack-loader",
+ "version": "0.1.0",
+ "license": "GPLv2"
+ }
+ }
+}
A => webpack-loader/package.json +8 -0
@@ 0,0 1,8 @@
+{
+ "name": "bee-webpack-loader",
+ "version": "0.1.0",
+ "description": "Webpack loader for Bee programming language .bee files",
+ "main": "index.js",
+ "author": "Yvan Sraka <yvan@sraka.xyz>",
+ "license": "GPLv2"
+}