diff --git a/Cargo.lock b/Cargo.lock index a80712dd..0b46760e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,96 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "ar_archive_writer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" +dependencies = [ + "object", +] + +[[package]] +name = "ariadne" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44055e597c674aef7cb903b2b9f6e4cba1277ed0d2d61dae7cd52d7ffa81f8e2" +dependencies = [ + "unicode-width", + "yansi", +] + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bitflags" version = "2.10.0" @@ -14,19 +104,196 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" dependencies = [ - "cfg_aliases", + "cfg_aliases 0.2.1", ] +[[package]] +name = "cc" +version = "1.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chumsky" +version = "1.0.0-alpha.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e82d74e6c83060ec269fe9e0d408d6de4a1645d525f9a0bbbb841ba4efd91ac" +dependencies = [ + "hashbrown 0.15.5", + "regex-automata", + "serde", + "stacker", + "unicode-ident", + "unicode-segmentation", +] + +[[package]] +name = "clap" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "ephapax-cli" +version = "0.1.0" +dependencies = [ + "ariadne", + "clap", + "colored", + "ephapax-interp", + "ephapax-lexer", + "ephapax-parser", + "ephapax-repl", + "ephapax-syntax", + "ephapax-typing", + "ephapax-wasm", + "smol_str", +] + +[[package]] +name = "ephapax-interp" +version = "0.1.0" +dependencies = [ + "ephapax-syntax", + "ephapax-typing", + "smol_str", + "thiserror", +] + +[[package]] +name = "ephapax-lexer" +version = "0.1.0" +dependencies = [ + "logos", + "smol_str", + "thiserror", +] + +[[package]] +name = "ephapax-parser" +version = "0.1.0" +dependencies = [ + "ariadne", + "chumsky", + "ephapax-lexer", + "ephapax-syntax", + "smol_str", + "thiserror", +] + +[[package]] +name = "ephapax-repl" +version = "0.1.0" +dependencies = [ + "colored", + "ephapax-interp", + "ephapax-lexer", + "ephapax-parser", + "ephapax-syntax", + "ephapax-typing", + "rustyline", + "smol_str", +] + [[package]] name = "ephapax-runtime" version = "0.1.0" +[[package]] +name = "ephapax-stdlib" +version = "0.1.0" +dependencies = [ + "ephapax-syntax", + "smol_str", +] + [[package]] name = "ephapax-syntax" version = "0.1.0" @@ -56,12 +323,83 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "indexmap" version = "2.12.1" @@ -69,15 +407,120 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "leb128" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "logos" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax 0.8.8", + "syn", +] + +[[package]] +name = "logos-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases 0.1.1", + "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_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "proc-macro2" version = "1.0.103" @@ -87,6 +530,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psm" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11f2fedc3b7dafdc2851bc52f277377c5473d378859be234bc7ebb593144d01" +dependencies = [ + "ar_archive_writer", + "cc", +] + [[package]] name = "quote" version = "1.0.42" @@ -96,12 +549,90 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "regex-automata" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustyline" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" +dependencies = [ + "bitflags", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix", + "radix_trie", + "unicode-segmentation", + "unicode-width", + "utf8parse", + "windows-sys 0.52.0", +] + [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -122,6 +653,18 @@ dependencies = [ "syn", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + [[package]] name = "smol_str" version = "0.3.4" @@ -132,6 +675,25 @@ dependencies = [ "serde_core", ] +[[package]] +name = "stacker" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.111" @@ -169,6 +731,24 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "wasm-encoder" version = "0.221.3" @@ -189,3 +769,106 @@ dependencies = [ "indexmap", "semver", ] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" diff --git a/Cargo.toml b/Cargo.toml index 5421c2cb..e0cb47d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,12 @@ members = [ "src/ephapax-typing", "src/ephapax-wasm", "src/ephapax-runtime", + "src/ephapax-lexer", + "src/ephapax-parser", + "src/ephapax-interp", + "src/ephapax-repl", + "src/ephapax-cli", + "src/ephapax-stdlib", ] [workspace.package] @@ -26,8 +32,19 @@ ephapax-syntax = { path = "src/ephapax-syntax" } ephapax-typing = { path = "src/ephapax-typing" } ephapax-wasm = { path = "src/ephapax-wasm" } ephapax-runtime = { path = "src/ephapax-runtime" } +ephapax-lexer = { path = "src/ephapax-lexer" } +ephapax-parser = { path = "src/ephapax-parser" } +ephapax-interp = { path = "src/ephapax-interp" } +ephapax-repl = { path = "src/ephapax-repl" } +ephapax-stdlib = { path = "src/ephapax-stdlib" } # External dependencies smol_str = "0.3" thiserror = "2" wasm-encoder = "0.221" +logos = "0.14" +chumsky = "1.0.0-alpha.7" +ariadne = "0.4" +clap = { version = "4", features = ["derive"] } +colored = "2" +rustyline = "14" diff --git a/MILESTONES.md b/MILESTONES.md index f51d82ac..fe704f18 100644 --- a/MILESTONES.md +++ b/MILESTONES.md @@ -56,16 +56,18 @@ cargo test -p ephapax-lexer --all-features | Task | Status | Verification | |------|--------|--------------| -| Parse let bindings | 🚧 | `cargo test -p ephapax-parser -- let_binding` | -| Parse function definitions | 🚧 | `cargo test -p ephapax-parser -- functions` | -| Parse function application | 🚧 | `cargo test -p ephapax-parser -- application` | -| Parse product types (pairs) | 🚧 | `cargo test -p ephapax-parser -- products` | -| Parse sum types | 🚧 | `cargo test -p ephapax-parser -- sums` | -| Parse region expressions | 🚧 | `cargo test -p ephapax-parser -- regions` | -| Parse borrow expressions | 🚧 | `cargo test -p ephapax-parser -- borrows` | -| Parse conditionals | 🚧 | `cargo test -p ephapax-parser -- conditionals` | +| Parse let bindings | ✅ | `cargo test -p ephapax-parser -- let_binding` | +| Parse function definitions | ✅ | `cargo test -p ephapax-parser -- functions` | +| Parse function application | ✅ | `cargo test -p ephapax-parser -- application` | +| Parse product types (pairs) | ✅ | `cargo test -p ephapax-parser -- products` | +| Parse sum types | ✅ | `cargo test -p ephapax-parser -- sums` | +| Parse region expressions | ✅ | `cargo test -p ephapax-parser -- regions` | +| Parse borrow expressions | ✅ | `cargo test -p ephapax-parser -- borrows` | +| Parse conditionals | ✅ | `cargo test -p ephapax-parser -- conditionals` | +| Parse binary operators | ✅ | Proper AST nodes for +,-,*,/,%,<,>,==,!=,&&,\|\| | +| Parse unary operators | ✅ | Proper AST nodes for !, - (negation) | +| Operator precedence | ✅ | Correct: unary > mul/div > add/sub > cmp > eq > and > or | | Error recovery with ariadne | 🔲 | Parse invalid input, emit ≥1 diagnostic | -| Operator precedence | 🔲 | `cargo test -p ephapax-parser -- precedence` | **Exit Criteria**: ```bash diff --git a/src/ephapax-interp/src/lib.rs b/src/ephapax-interp/src/lib.rs index e558e465..05fab785 100644 --- a/src/ephapax-interp/src/lib.rs +++ b/src/ephapax-interp/src/lib.rs @@ -6,7 +6,7 @@ //! A simple interpreter for debugging and rapid development. //! Useful for testing before compiling to WASM. -use ephapax_syntax::{BaseTy, Decl, Expr, ExprKind, Literal, Module, RegionName, Ty, Var}; +use ephapax_syntax::{BaseTy, BinOp, Decl, Expr, ExprKind, Literal, Module, RegionName, Ty, UnaryOp, Var}; use smol_str::SmolStr; use std::collections::HashMap; use thiserror::Error; @@ -236,6 +236,140 @@ impl Interpreter { ExprKind::Drop(inner) => self.eval_drop(inner), ExprKind::Copy(inner) => self.eval_copy(inner), ExprKind::Block(exprs) => self.eval_block(exprs), + ExprKind::BinOp { op, left, right } => self.eval_binop(*op, left, right), + ExprKind::UnaryOp { op, operand } => self.eval_unaryop(*op, operand), + } + } + + fn eval_binop(&mut self, op: BinOp, left: &Expr, right: &Expr) -> Result { + let left_val = self.eval(left)?; + let right_val = self.eval(right)?; + + match op { + BinOp::Add => self.numeric_binop(left_val, right_val, |a, b| a + b, |a, b| a + b), + BinOp::Sub => self.numeric_binop(left_val, right_val, |a, b| a - b, |a, b| a - b), + BinOp::Mul => self.numeric_binop(left_val, right_val, |a, b| a * b, |a, b| a * b), + BinOp::Div => { + // Check for division by zero for integers + match (&left_val, &right_val) { + (Value::I32(_), Value::I32(0)) | (Value::I64(_), Value::I64(0)) => { + return Err(RuntimeError::DivisionByZero); + } + _ => {} + } + self.numeric_binop(left_val, right_val, |a, b| a / b, |a, b| a / b) + } + BinOp::Mod => { + match (&left_val, &right_val) { + (Value::I32(_), Value::I32(0)) | (Value::I64(_), Value::I64(0)) => { + return Err(RuntimeError::DivisionByZero); + } + _ => {} + } + self.numeric_binop(left_val, right_val, |a, b| a % b, |a, b| a % b) + } + BinOp::Lt => self.compare_op(left_val, right_val, |a, b| a < b, |a, b| a < b), + BinOp::Le => self.compare_op(left_val, right_val, |a, b| a <= b, |a, b| a <= b), + BinOp::Gt => self.compare_op(left_val, right_val, |a, b| a > b, |a, b| a > b), + BinOp::Ge => self.compare_op(left_val, right_val, |a, b| a >= b, |a, b| a >= b), + BinOp::Eq => Ok(Value::Bool(self.values_equal(&left_val, &right_val))), + BinOp::Ne => Ok(Value::Bool(!self.values_equal(&left_val, &right_val))), + BinOp::And => match (left_val, right_val) { + (Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(a && b)), + (l, r) => Err(RuntimeError::TypeError { + expected: "Bool".to_string(), + found: format!("{}, {}", l.type_name(), r.type_name()), + }), + }, + BinOp::Or => match (left_val, right_val) { + (Value::Bool(a), Value::Bool(b)) => Ok(Value::Bool(a || b)), + (l, r) => Err(RuntimeError::TypeError { + expected: "Bool".to_string(), + found: format!("{}, {}", l.type_name(), r.type_name()), + }), + }, + } + } + + fn numeric_binop( + &self, + left: Value, + right: Value, + int_op: I, + float_op: F, + ) -> Result + where + I: Fn(i64, i64) -> i64, + F: Fn(f64, f64) -> f64, + { + match (left, right) { + (Value::I32(a), Value::I32(b)) => Ok(Value::I32(int_op(a as i64, b as i64) as i32)), + (Value::I64(a), Value::I64(b)) => Ok(Value::I64(int_op(a, b))), + (Value::F32(a), Value::F32(b)) => Ok(Value::F32(float_op(a as f64, b as f64) as f32)), + (Value::F64(a), Value::F64(b)) => Ok(Value::F64(float_op(a, b))), + (l, r) => Err(RuntimeError::TypeError { + expected: "numeric type".to_string(), + found: format!("{}, {}", l.type_name(), r.type_name()), + }), + } + } + + fn compare_op( + &self, + left: Value, + right: Value, + int_op: I, + float_op: F, + ) -> Result + where + I: Fn(i64, i64) -> bool, + F: Fn(f64, f64) -> bool, + { + match (left, right) { + (Value::I32(a), Value::I32(b)) => Ok(Value::Bool(int_op(a as i64, b as i64))), + (Value::I64(a), Value::I64(b)) => Ok(Value::Bool(int_op(a, b))), + (Value::F32(a), Value::F32(b)) => Ok(Value::Bool(float_op(a as f64, b as f64))), + (Value::F64(a), Value::F64(b)) => Ok(Value::Bool(float_op(a, b))), + (l, r) => Err(RuntimeError::TypeError { + expected: "numeric type".to_string(), + found: format!("{}, {}", l.type_name(), r.type_name()), + }), + } + } + + fn values_equal(&self, left: &Value, right: &Value) -> bool { + match (left, right) { + (Value::Unit, Value::Unit) => true, + (Value::Bool(a), Value::Bool(b)) => a == b, + (Value::I32(a), Value::I32(b)) => a == b, + (Value::I64(a), Value::I64(b)) => a == b, + (Value::F32(a), Value::F32(b)) => a == b, + (Value::F64(a), Value::F64(b)) => a == b, + (Value::String { data: d1, .. }, Value::String { data: d2, .. }) => d1 == d2, + _ => false, + } + } + + fn eval_unaryop(&mut self, op: UnaryOp, operand: &Expr) -> Result { + let val = self.eval(operand)?; + match op { + UnaryOp::Not => match val { + Value::Bool(b) => Ok(Value::Bool(!b)), + v => Err(RuntimeError::TypeError { + expected: "Bool".to_string(), + found: v.type_name().to_string(), + }), + }, + UnaryOp::Neg => match val { + Value::I32(n) => Ok(Value::I32(-n)), + Value::I64(n) => Ok(Value::I64(-n)), + Value::F32(n) => Ok(Value::F32(-n)), + Value::F64(n) => Ok(Value::F64(-n)), + v => Err(RuntimeError::TypeError { + expected: "numeric type".to_string(), + found: v.type_name().to_string(), + }), + }, } } diff --git a/src/ephapax-parser/src/lib.rs b/src/ephapax-parser/src/lib.rs index 8fe1f0b5..dd3acf83 100644 --- a/src/ephapax-parser/src/lib.rs +++ b/src/ephapax-parser/src/lib.rs @@ -16,7 +16,7 @@ use chumsky::prelude::*; use ephapax_lexer::{Lexer, Span as LexerSpan, TokenKind}; -use ephapax_syntax::{BaseTy, Decl, Expr, ExprKind, Literal, Module, Span as SyntaxSpan, Ty}; +use ephapax_syntax::{BaseTy, BinOp, Decl, Expr, ExprKind, Literal, Module, Span as SyntaxSpan, Ty, UnaryOp}; use smol_str::SmolStr; pub mod error; @@ -650,75 +650,157 @@ fn expr_parser<'a>() -> impl Parser<'a, &'a [SpannedToken], Expr, extra::Err <= >= let comparison = sum.clone().foldl( choice(( - tok(TokenKind::Lt), - tok(TokenKind::Gt), - tok(TokenKind::LtEq), - tok(TokenKind::GtEq), + token(TokenKind::Lt).map(|_| BinOp::Lt), + token(TokenKind::Gt).map(|_| BinOp::Gt), + token(TokenKind::LtEq).map(|_| BinOp::Le), + token(TokenKind::GtEq).map(|_| BinOp::Ge), )) .then(sum.clone()) .repeated(), - |left, (_, right)| { + |left, (op, right)| { let span = merge_spans(left.span, right.span); - Expr::new(ExprKind::Lit(Literal::Bool(false)), span) + Expr::new( + ExprKind::BinOp { + op, + left: Box::new(left), + right: Box::new(right), + }, + span, + ) }, ); + // Equality: == != let equality = comparison.clone().foldl( - choice((tok(TokenKind::EqEq), tok(TokenKind::NotEq))) - .then(comparison.clone()) - .repeated(), - |left, (_, right)| { + choice(( + token(TokenKind::EqEq).map(|_| BinOp::Eq), + token(TokenKind::NotEq).map(|_| BinOp::Ne), + )) + .then(comparison.clone()) + .repeated(), + |left, (op, right)| { let span = merge_spans(left.span, right.span); - Expr::new(ExprKind::Lit(Literal::Bool(false)), span) + Expr::new( + ExprKind::BinOp { + op, + left: Box::new(left), + right: Box::new(right), + }, + span, + ) }, ); + // Logical AND: && let and = equality.clone().foldl( - tok(TokenKind::AndAnd) + token(TokenKind::AndAnd) + .map(|_| BinOp::And) .then(equality.clone()) .repeated(), - |left, (_, right)| { + |left, (op, right)| { let span = merge_spans(left.span, right.span); - Expr::new(ExprKind::Lit(Literal::Bool(false)), span) + Expr::new( + ExprKind::BinOp { + op, + left: Box::new(left), + right: Box::new(right), + }, + span, + ) }, ); + // Logical OR: || and.clone().foldl( - tok(TokenKind::OrOr) + token(TokenKind::OrOr) + .map(|_| BinOp::Or) .then(and.clone()) .repeated(), - |left, (_, right)| { + |left, (op, right)| { let span = merge_spans(left.span, right.span); - Expr::new(ExprKind::Lit(Literal::Bool(false)), span) + Expr::new( + ExprKind::BinOp { + op, + left: Box::new(left), + right: Box::new(right), + }, + span, + ) }, ) }) diff --git a/src/ephapax-syntax/src/lib.rs b/src/ephapax-syntax/src/lib.rs index 7d5ce3d3..60ec0480 100644 --- a/src/ephapax-syntax/src/lib.rs +++ b/src/ephapax-syntax/src/lib.rs @@ -111,6 +111,36 @@ pub enum Literal { String(String), } +/// Binary operators +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum BinOp { + // Arithmetic + Add, + Sub, + Mul, + Div, + Mod, + // Comparison + Lt, + Le, + Gt, + Ge, + Eq, + Ne, + // Logical + And, + Or, +} + +/// Unary operators +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum UnaryOp { + /// Logical negation + Not, + /// Arithmetic negation + Neg, +} + /// Pattern for destructuring #[derive(Debug, Clone, PartialEq)] pub enum Pattern { @@ -232,6 +262,17 @@ pub enum ExprKind { // ===== Blocks ===== /// Sequence of expressions Block(Vec), + + // ===== Operators ===== + /// Binary operation: e1 op e2 + BinOp { + op: BinOp, + left: Box, + right: Box, + }, + + /// Unary operation: op e + UnaryOp { op: UnaryOp, operand: Box }, } impl Expr {