1
0

Compare commits

..

No commits in common. "dfee50003a479f7705eac0980e61c0c06adb9d9d" and "b81c65629bc9a80997a7ec9947fe4be1bba68153" have entirely different histories.

11 changed files with 343 additions and 295 deletions

327
Cargo.lock generated
View File

@ -2,6 +2,18 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.1.2" version = "1.1.2"
@ -11,6 +23,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.13" version = "0.6.13"
@ -46,7 +64,7 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [ dependencies = [
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -56,21 +74,100 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"windows-sys", "windows-sys 0.52.0",
] ]
[[package]]
name = "ariadne"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd002a6223f12c7a95cdd4b1cb3a0149d22d37f7a9ecdb2cb691a071fe236c29"
dependencies = [
"unicode-width",
"yansi",
]
[[package]]
name = "cc"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chumsky"
version = "1.0.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9c28d4e5dd9a9262a38b231153591da6ce1471b818233f4727985d3dd0ed93c"
dependencies = [
"hashbrown",
"regex-automata 0.3.9",
"serde",
"stacker",
"unicode-ident",
]
[[package]]
name = "clap"
version = "4.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "colored"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
dependencies = [
"lazy_static",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.8.5" version = "0.8.5"
@ -100,7 +197,12 @@ checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
name = "dust-lang" name = "dust-lang"
version = "0.5.0" version = "0.5.0"
dependencies = [ dependencies = [
"ariadne",
"chumsky",
"clap",
"colored",
"env_logger", "env_logger",
"log",
"rand", "rand",
"rayon", "rayon",
"serde", "serde",
@ -151,6 +253,22 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "humantime" name = "humantime"
version = "2.1.0" version = "2.1.0"
@ -163,6 +281,12 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.153"
@ -181,6 +305,12 @@ version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.17"
@ -196,6 +326,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "psm"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.35" version = "1.0.35"
@ -263,8 +402,19 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-automata", "regex-automata 0.4.6",
"regex-syntax", "regex-syntax 0.8.2",
]
[[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]] [[package]]
@ -275,9 +425,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-syntax", "regex-syntax 0.8.2",
] ]
[[package]]
name = "regex-syntax"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.8.2" version = "0.8.2"
@ -321,6 +477,25 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "stacker"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
dependencies = [
"cc",
"cfg-if",
"libc",
"psm",
"winapi",
]
[[package]]
name = "strsim"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.53" version = "2.0.53"
@ -338,25 +513,83 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.4",
]
[[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]] [[package]]
@ -365,53 +598,121 @@ version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.52.4",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.52.4",
"windows_i686_gnu", "windows_i686_gnu 0.52.4",
"windows_i686_msvc", "windows_i686_msvc 0.52.4",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.52.4",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.52.4",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.52.4",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.4" version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -9,7 +9,12 @@ readme.workspace = true
repository.workspace = true repository.workspace = true
[dependencies] [dependencies]
ariadne = "0.4.0"
chumsky = { version = "1.0.0-alpha.6", features = ["pratt", "label"] }
clap = { version = "4.5.2", features = ["derive"] }
colored = "2.1.0"
env_logger = "0.11.3" env_logger = "0.11.3"
log = "0.4.21"
rand = "0.8.5" rand = "0.8.5"
rayon = "1.9.0" rayon = "1.9.0"
serde = { version = "1.0.203", features = ["derive"] } serde = { version = "1.0.203", features = ["derive"] }

View File

@ -1,4 +1,4 @@
use crate::{Identifier, ReservedIdentifier, Span, Value}; use crate::{Identifier, Span, Value};
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Node { pub struct Node {
@ -22,12 +22,10 @@ pub enum Statement {
// Expressions // Expressions
Add(Box<Node>, Box<Node>), Add(Box<Node>, Box<Node>),
PropertyAccess(Box<Node>, Box<Node>),
List(Vec<Node>), List(Vec<Node>),
Multiply(Box<Node>, Box<Node>), Multiply(Box<Node>, Box<Node>),
// Hard-coded values // Hard-coded values
Constant(Value), Constant(Value),
Identifier(Identifier), Identifier(Identifier),
ReservedIdentifier(ReservedIdentifier),
} }

View File

@ -1,4 +1,4 @@
use crate::{Node, Statement}; use crate::{Node, Span, Statement};
pub fn analyze(abstract_tree: Vec<Node>) -> Result<(), AnalyzerError> { pub fn analyze(abstract_tree: Vec<Node>) -> Result<(), AnalyzerError> {
let analyzer = Analyzer::new(abstract_tree); let analyzer = Analyzer::new(abstract_tree);
@ -55,18 +55,6 @@ impl Analyzer {
self.analyze_node(&left)?; self.analyze_node(&left)?;
self.analyze_node(&right)?; self.analyze_node(&right)?;
} }
Statement::PropertyAccess(left, right) => {
if let Statement::Identifier(_) = &left.statement {
// Identifier is in the correct position
} else {
return Err(AnalyzerError::ExpectedIdentifier {
actual: left.as_ref().clone(),
});
}
self.analyze_node(&right)?;
}
Statement::ReservedIdentifier(_) => {}
} }
Ok(()) Ok(())

View File

@ -5,7 +5,7 @@
//! - [`Lexer`], which lexes the input a token at a time //! - [`Lexer`], which lexes the input a token at a time
use std::num::{ParseFloatError, ParseIntError}; use std::num::{ParseFloatError, ParseIntError};
use crate::{Identifier, ReservedIdentifier, Span, Token}; use crate::{Identifier, Span, Token};
/// Lex the input and return a vector of tokens and their positions. /// Lex the input and return a vector of tokens and their positions.
pub fn lex(input: &str) -> Result<Vec<(Token, Span)>, LexError> { pub fn lex(input: &str) -> Result<Vec<(Token, Span)>, LexError> {
@ -90,10 +90,6 @@ impl<'a> Lexer<'a> {
self.position += 1; self.position += 1;
(Token::Comma, (self.position - 1, self.position)) (Token::Comma, (self.position - 1, self.position))
} }
'.' => {
self.position += 1;
(Token::Dot, (self.position - 1, self.position))
}
_ => (Token::Eof, (self.position, self.position)), _ => (Token::Eof, (self.position, self.position)),
} }
} else { } else {
@ -119,11 +115,6 @@ impl<'a> Lexer<'a> {
self.source[self.position..].chars().next() self.source[self.position..].chars().next()
} }
/// Peek at the second-to-next character without consuming it.
fn peek_second_char(&self) -> Option<char> {
self.source[self.position..].chars().nth(1)
}
/// Lex an integer or float token. /// Lex an integer or float token.
fn lex_number(&mut self) -> Result<(Token, Span), LexError> { fn lex_number(&mut self) -> Result<(Token, Span), LexError> {
let start_pos = self.position; let start_pos = self.position;
@ -131,20 +122,16 @@ impl<'a> Lexer<'a> {
while let Some(c) = self.peek_char() { while let Some(c) = self.peek_char() {
if c == '.' { if c == '.' {
if let Some('0'..='9') = self.peek_second_char() { is_float = true;
if !is_float {
self.next_char();
while let Some(c) = self.peek_char() {
if c.is_ascii_digit() {
self.next_char(); self.next_char();
} else {
break;
} }
self.next_char();
while let Some('0'..='9') = self.peek_char() {
self.next_char();
}
is_float = true;
} else {
break;
} }
} }
@ -171,20 +158,15 @@ impl<'a> Lexer<'a> {
let start_pos = self.position; let start_pos = self.position;
while let Some(c) = self.peek_char() { while let Some(c) = self.peek_char() {
if c.is_ascii_alphanumeric() || c == '_' { if c.is_ascii_alphanumeric() {
self.next_char(); self.next_char();
} else { } else {
break; break;
} }
} }
let string = &self.source[start_pos..self.position]; let identifier = &self.source[start_pos..self.position];
let token = match string { let token = Token::Identifier(Identifier::new(identifier));
"is_even" => Token::ReservedIdentifier(ReservedIdentifier::IsEven),
"is_odd" => Token::ReservedIdentifier(ReservedIdentifier::IsOdd),
"length" => Token::ReservedIdentifier(ReservedIdentifier::Length),
_ => Token::Identifier(Identifier::new(string)),
};
Ok((token, (start_pos, self.position))) Ok((token, (start_pos, self.position)))
} }
@ -212,47 +194,6 @@ impl From<ParseIntError> for LexError {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn integer_property_access() {
let input = "42.is_even";
assert_eq!(
lex(input),
Ok(vec![
(Token::Integer(42), (0, 2)),
(Token::Dot, (2, 3)),
(
Token::ReservedIdentifier(ReservedIdentifier::IsEven),
(3, 10)
),
(Token::Eof, (10, 10)),
])
)
}
#[test]
fn empty() {
let input = "";
assert_eq!(lex(input), Ok(vec![(Token::Eof, (0, 0))]))
}
#[test]
fn reserved_identifier() {
let input = "length";
assert_eq!(
lex(input),
Ok(vec![
(
Token::ReservedIdentifier(ReservedIdentifier::Length),
(0, 6)
),
(Token::Eof, (6, 6)),
])
)
}
#[test] #[test]
fn square_braces() { fn square_braces() {
let input = "[]"; let input = "[]";

View File

@ -21,7 +21,7 @@ pub use identifier::Identifier;
pub use lex::{lex, LexError, Lexer}; pub use lex::{lex, LexError, Lexer};
pub use parse::{parse, ParseError, Parser}; pub use parse::{parse, ParseError, Parser};
pub use r#type::Type; pub use r#type::Type;
pub use token::{ReservedIdentifier, Token}; pub use token::Token;
pub use value::{Value, ValueError}; pub use value::{Value, ValueError};
pub use vm::{run, Vm, VmError}; pub use vm::{run, Vm, VmError};

View File

@ -85,17 +85,6 @@ impl<'src> Parser<'src> {
(left_start, right_end), (left_start, right_end),
)); ));
} }
(Token::Dot, _) => {
self.next_token()?;
let right_node = self.parse_node(self.current_precedence())?;
let right_end = right_node.span.1;
return Ok(Node::new(
Statement::PropertyAccess(Box::new(left_node), Box::new(right_node)),
(left_start, right_end),
));
}
_ => {} _ => {}
} }
} }
@ -170,21 +159,12 @@ impl<'src> Parser<'src> {
} }
} }
} }
(Token::ReservedIdentifier(reserved), _) => {
self.next_token()?;
Ok(Node::new(
Statement::ReservedIdentifier(reserved),
self.current.1,
))
}
_ => Err(ParseError::UnexpectedToken(self.current.0.clone())), _ => Err(ParseError::UnexpectedToken(self.current.0.clone())),
} }
} }
fn current_precedence(&self) -> u8 { fn current_precedence(&self) -> u8 {
match self.current.0 { match self.current.0 {
Token::Dot => 4,
Token::Equal => 3, Token::Equal => 3,
Token::Plus => 1, Token::Plus => 1,
Token::Star => 2, Token::Star => 2,
@ -213,53 +193,6 @@ mod tests {
use super::*; use super::*;
#[test]
fn list_access() {
let input = "[1, 2, 3].0";
assert_eq!(
parse(input),
Ok([Node::new(
Statement::PropertyAccess(
Box::new(Node::new(
Statement::List(vec![
Node::new(Statement::Constant(Value::integer(1)), (1, 2)),
Node::new(Statement::Constant(Value::integer(2)), (4, 5)),
Node::new(Statement::Constant(Value::integer(3)), (7, 8)),
]),
(0, 9)
)),
Box::new(Node::new(Statement::Constant(Value::integer(0)), (10, 11))),
),
(0, 11),
)]
.into())
);
}
#[test]
fn property_access() {
let input = "a.b";
assert_eq!(
parse(input),
Ok([Node::new(
Statement::PropertyAccess(
Box::new(Node::new(
Statement::Identifier(Identifier::new("a")),
(0, 1)
)),
Box::new(Node::new(
Statement::Identifier(Identifier::new("b")),
(2, 3)
)),
),
(0, 3),
)]
.into())
);
}
#[test] #[test]
fn complex_list() { fn complex_list() {
let input = "[1, 1 + 1, 2 + (4 * 10)]"; let input = "[1, 1 + 1, 2 + (4 * 10)]";

View File

@ -3,11 +3,9 @@ use crate::Identifier;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Token { pub enum Token {
Comma, Comma,
Dot,
Eof, Eof,
Equal, Equal,
Identifier(Identifier), Identifier(Identifier),
ReservedIdentifier(ReservedIdentifier),
Integer(i64), Integer(i64),
Plus, Plus,
Star, Star,
@ -17,10 +15,3 @@ pub enum Token {
RightSquareBrace, RightSquareBrace,
Float(f64), Float(f64),
} }
#[derive(Debug, PartialEq, Clone)]
pub enum ReservedIdentifier {
IsEven,
IsOdd,
Length,
}

View File

@ -16,6 +16,7 @@ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
}; };
use clap::error::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::identifier::Identifier; use crate::identifier::Identifier;

View File

@ -6,6 +6,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use chumsky::container::Container;
use serde::{ use serde::{
de::Visitor, de::Visitor,
ser::{SerializeMap, SerializeSeq, SerializeTuple}, ser::{SerializeMap, SerializeSeq, SerializeTuple},
@ -401,7 +402,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
where where
A: serde::de::MapAccess<'de>, A: serde::de::MapAccess<'de>,
{ {
let mut btree = BTreeMap::new(); let mut btree = BTreeMap::with_capacity(map.size_hint().unwrap_or(10));
while let Some((key, value)) = map.next_entry()? { while let Some((key, value)) = map.next_entry()? {
btree.insert(key, value); btree.insert(key, value);
@ -457,7 +458,7 @@ impl ValueInner {
} }
} }
ValueInner::Map(value_map) => { ValueInner::Map(value_map) => {
let mut type_map = BTreeMap::new(); let mut type_map = BTreeMap::with_capacity(value_map.len());
for (identifier, value) in value_map { for (identifier, value) in value_map {
let r#type = value.r#type(); let r#type = value.r#type();
@ -473,18 +474,6 @@ impl ValueInner {
} }
} }
pub trait ValueProperties<'a> {}
pub struct IntegerProperties<'a>(&'a Value);
impl<'a> IntegerProperties<'a> {
pub fn is_even(&self) -> bool {
self.0.as_integer().unwrap() % 2 == 0
}
}
impl<'a> ValueProperties<'a> for IntegerProperties<'a> {}
impl Eq for ValueInner {} impl Eq for ValueInner {}
impl PartialOrd for ValueInner { impl PartialOrd for ValueInner {
@ -527,7 +516,4 @@ impl Ord for ValueInner {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum ValueError { pub enum ValueError {
CannotAdd(Value, Value), CannotAdd(Value, Value),
PropertyNotFound { value: Value, property: Identifier },
IndexOutOfBounds { value: Value, index: i64 },
ExpectedList(Value),
} }

View File

@ -1,15 +1,13 @@
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use crate::{ use crate::{parse, Identifier, Node, ParseError, Span, Statement, Value, ValueError};
parse, Identifier, Node, ParseError, ReservedIdentifier, Span, Statement, Value, ValueError,
};
pub fn run( pub fn run(
input: &str, input: &str,
variables: &mut HashMap<Identifier, Value>, variables: &mut HashMap<Identifier, Value>,
) -> Result<Option<Value>, VmError> { ) -> Result<Option<Value>, VmError> {
let abstract_syntax_tree = parse(input)?; let instructions = parse(input)?;
let mut vm = Vm::new(abstract_syntax_tree); let mut vm = Vm::new(instructions);
vm.run(variables) vm.run(variables)
} }
@ -42,9 +40,6 @@ impl Vm {
variables: &mut HashMap<Identifier, Value>, variables: &mut HashMap<Identifier, Value>,
) -> Result<Option<Value>, VmError> { ) -> Result<Option<Value>, VmError> {
match node.statement { match node.statement {
Statement::Constant(value) => Ok(Some(value.clone())),
Statement::Identifier(_) => Ok(None),
Statement::ReservedIdentifier(_) => Ok(None),
Statement::Add(left, right) => { Statement::Add(left, right) => {
let left_span = left.span; let left_span = left.span;
let left = if let Some(value) = self.run_node(*left, variables)? { let left = if let Some(value) = self.run_node(*left, variables)? {
@ -87,6 +82,8 @@ impl Vm {
Ok(None) Ok(None)
} }
Statement::Constant(value) => Ok(Some(value.clone())),
Statement::Identifier(_) => Ok(None),
Statement::List(nodes) => { Statement::List(nodes) => {
let values = nodes let values = nodes
.into_iter() .into_iter()
@ -103,62 +100,6 @@ impl Vm {
Ok(Some(Value::list(values))) Ok(Some(Value::list(values)))
} }
Statement::Multiply(_, _) => todo!(), Statement::Multiply(_, _) => todo!(),
Statement::PropertyAccess(left, right) => {
let left_span = left.span;
let left = if let Some(value) = self.run_node(*left, variables)? {
value
} else {
return Err(VmError::ExpectedValue {
position: left_span,
});
};
let right_span = right.span;
if let Statement::ReservedIdentifier(reserved) = &right.statement {
match reserved {
ReservedIdentifier::IsEven => {
if let Some(integer) = left.as_integer() {
return Ok(Some(Value::boolean(integer % 2 == 0)));
} else {
return Err(VmError::ExpectedInteger {
position: right_span,
});
}
}
ReservedIdentifier::IsOdd => {
if let Some(integer) = left.as_integer() {
return Ok(Some(Value::boolean(integer % 2 != 0)));
} else {
return Err(VmError::ExpectedInteger {
position: right_span,
});
}
}
ReservedIdentifier::Length => {
if let Some(list) = left.as_list() {
return Ok(Some(Value::integer(list.len() as i64)));
} else {
return Err(VmError::ExpectedList {
position: right_span,
});
}
}
}
}
if let (Some(list), Statement::Constant(value)) = (left.as_list(), &right.statement)
{
if let Some(index) = value.as_integer() {
let value = list.get(index as usize).cloned();
return Ok(value);
}
}
Err(VmError::ExpectedIdentifierOrInteger {
position: right_span,
})
}
} }
} }
} }
@ -171,9 +112,6 @@ pub enum VmError {
// Anaylsis Failures // Anaylsis Failures
// These should be prevented by running the analyzer before the VM // These should be prevented by running the analyzer before the VM
ExpectedValue { position: Span }, ExpectedValue { position: Span },
ExpectedIdentifierOrInteger { position: Span },
ExpectedList { position: Span },
ExpectedInteger { position: Span },
} }
impl From<ParseError> for VmError { impl From<ParseError> for VmError {
@ -192,40 +130,6 @@ impl From<ValueError> for VmError {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn is_even() {
let input = "42.is_even";
assert_eq!(
run(input, &mut HashMap::new()),
Ok(Some(Value::boolean(true)))
);
}
#[test]
fn is_odd() {
let input = "42.is_odd";
assert_eq!(
run(input, &mut HashMap::new()),
Ok(Some(Value::boolean(false)))
);
}
#[test]
fn list_access() {
let input = "[1, 2, 3].1";
assert_eq!(run(input, &mut HashMap::new()), Ok(Some(Value::integer(2))));
}
#[test]
fn property_access() {
let input = "[1, 2, 3].length";
assert_eq!(run(input, &mut HashMap::new()), Ok(Some(Value::integer(3))));
}
#[test] #[test]
fn add() { fn add() {
let input = "1 + 2"; let input = "1 + 2";