mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
Some function stuff
It's not done, but honestly it's getting too tedious. I will need to rethink how I'm doing it.
This commit is contained in:
parent
3f3ea4153a
commit
2b876da56f
13 changed files with 14927 additions and 3467 deletions
130
Cargo.lock
generated
130
Cargo.lock
generated
|
@ -84,7 +84,7 @@ name = "atty"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -102,7 +102,7 @@ dependencies = [
|
||||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ version = "0.1.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -240,7 +240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ dependencies = [
|
||||||
"clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -357,7 +357,7 @@ version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -498,7 +498,7 @@ name = "ctrlc"
|
||||||
version = "3.1.3"
|
version = "3.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nix 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ version = "0.4.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -528,7 +528,7 @@ dependencies = [
|
||||||
"enumset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"enumset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hashbrown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hashbrown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -648,7 +648,7 @@ name = "directories"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -657,7 +657,7 @@ name = "dirs"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -677,7 +677,7 @@ version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -871,7 +871,7 @@ version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1023,7 +1023,7 @@ version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1156,7 +1156,7 @@ name = "iovec"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1171,7 +1171,7 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1251,7 +1251,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.55"
|
version = "0.2.58"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1261,7 +1261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1274,7 +1274,7 @@ version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1287,7 +1287,7 @@ version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1365,7 +1365,7 @@ name = "malloc_buf"
|
||||||
version = "0.0.6"
|
version = "0.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1383,7 +1383,7 @@ name = "memchr"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1416,7 +1416,7 @@ version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1434,7 +1434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1447,7 +1447,7 @@ dependencies = [
|
||||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1472,7 +1472,7 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1489,7 +1489,7 @@ version = "5.99.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1499,19 +1499,19 @@ version = "0.2.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.14.0"
|
version = "0.14.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1576,6 +1576,7 @@ dependencies = [
|
||||||
"nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pretty 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1666,7 +1667,7 @@ name = "num_cpus"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1716,7 +1717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"onig_sys 69.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1738,7 +1739,7 @@ dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1754,7 +1755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1793,7 +1794,7 @@ name = "pancurses"
|
||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pdcurses-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pdcurses-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1824,7 +1825,7 @@ name = "parking_lot_core"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1838,7 +1839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1860,7 +1861,7 @@ version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1935,6 +1936,14 @@ dependencies = [
|
||||||
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"typed-arena 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pretty_assertions"
|
name = "pretty_assertions"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
|
@ -2044,7 +2053,7 @@ version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2099,7 +2108,7 @@ name = "rand_jitter"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -2111,7 +2120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2151,7 +2160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2289,10 +2298,10 @@ version = "4.1.0"
|
||||||
source = "git+https://github.com/kkawakam/rustyline.git#cad8b2fc0b253831aaff143bdce5d2abec66a9c9"
|
source = "git+https://github.com/kkawakam/rustyline.git#cad8b2fc0b253831aaff143bdce5d2abec66a9c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nix 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2348,7 +2357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2488,7 +2497,7 @@ name = "signal-hook"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"signal-hook-registry 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"signal-hook-registry 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2498,7 +2507,7 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2558,7 +2567,7 @@ version = "0.1.19"
|
||||||
source = "git+https://github.com/jonathandturner/rust-subprocess.git?branch=is_already_escaped#6d184a680d825da4f365c063db1c4f9db3d64ba6"
|
source = "git+https://github.com/jonathandturner/rust-subprocess.git?branch=is_already_escaped#6d184a680d825da4f365c063db1c4f9db3d64ba6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2620,7 +2629,7 @@ version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -2631,7 +2640,7 @@ version = "3.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2654,7 +2663,7 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2671,7 +2680,7 @@ name = "termion"
|
||||||
version = "1.5.2"
|
version = "1.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2682,7 +2691,7 @@ name = "termios"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2706,7 +2715,7 @@ name = "time"
|
||||||
version = "0.1.42"
|
version = "0.1.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -2914,6 +2923,11 @@ dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typed-arena"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ucd-util"
|
name = "ucd-util"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -3118,7 +3132,7 @@ name = "xcb"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3285,7 +3299,7 @@ dependencies = [
|
||||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||||
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||||
"checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e"
|
"checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e"
|
||||||
"checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880"
|
"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319"
|
||||||
"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1"
|
"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1"
|
||||||
"checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
|
"checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
|
||||||
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||||
|
@ -3312,7 +3326,7 @@ dependencies = [
|
||||||
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
|
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
|
||||||
"checksum ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82"
|
"checksum ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82"
|
||||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
"checksum nix 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d10caafde29a846a82ae0af70414e4643e072993441033b2c93217957e2f867"
|
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
"checksum nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)" = "6527f311b2baba609e980e008460ab5ebff6d6da15213bb8eb193b7746eefa24"
|
"checksum nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)" = "6527f311b2baba609e980e008460ab5ebff6d6da15213bb8eb193b7746eefa24"
|
||||||
|
@ -3354,6 +3368,7 @@ dependencies = [
|
||||||
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
|
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
|
||||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||||
"checksum plist 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f4739851c08dd9a62a78beff2edf1a438517268b2c563c42fc6d9d3139e42d2a"
|
"checksum plist 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f4739851c08dd9a62a78beff2edf1a438517268b2c563c42fc6d9d3139e42d2a"
|
||||||
|
"checksum pretty 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f60c0d9f6fc88ecdd245d90c1920ff76a430ab34303fc778d33b1d0a4c3bf6d3"
|
||||||
"checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
|
"checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
|
||||||
"checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
|
"checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
|
||||||
"checksum prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2705417f8aa07cb6308db42e55623479c1c9667942a4d5e4174c684e5da5590d"
|
"checksum prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2705417f8aa07cb6308db42e55623479c1c9667942a4d5e4174c684e5da5590d"
|
||||||
|
@ -3457,6 +3472,7 @@ dependencies = [
|
||||||
"checksum toml-query_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c99ca245ec273c7e75c8ee58f47b882d0146f3c2c8495158082c6671e8b5335"
|
"checksum toml-query_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c99ca245ec273c7e75c8ee58f47b882d0146f3c2c8495158082c6671e8b5335"
|
||||||
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||||
"checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b"
|
"checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b"
|
||||||
|
"checksum typed-arena 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6c06a92aef38bb4dc5b0df00d68496fc31307c5344c867bb61678c6e1671ec5"
|
||||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||||
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
||||||
"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
|
"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
|
||||||
|
|
|
@ -59,6 +59,7 @@ ctrlc = "3.1.3"
|
||||||
ptree = "0.2"
|
ptree = "0.2"
|
||||||
clipboard = "0.5"
|
clipboard = "0.5"
|
||||||
reqwest = "0.9"
|
reqwest = "0.9"
|
||||||
|
pretty = "0.5.2"
|
||||||
|
|
||||||
[dependencies.pancurses]
|
[dependencies.pancurses]
|
||||||
version = "0.16"
|
version = "0.16"
|
||||||
|
|
|
@ -9,14 +9,33 @@ crate use ast::Pipeline;
|
||||||
crate use registry::{Args, CommandConfig};
|
crate use registry::{Args, CommandConfig};
|
||||||
|
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
|
use ast::Module;
|
||||||
use lexer::Lexer;
|
use lexer::Lexer;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use parser::PipelineParser;
|
use parser::{ModuleParser, ReplLineParser};
|
||||||
|
|
||||||
pub fn parse(input: &str) -> Result<Pipeline, ShellError> {
|
pub fn parse(input: &str) -> Result<Pipeline, ShellError> {
|
||||||
let _ = pretty_env_logger::try_init();
|
let _ = pretty_env_logger::try_init();
|
||||||
|
|
||||||
let parser = PipelineParser::new();
|
let parser = ReplLineParser::new();
|
||||||
|
let tokens = Lexer::new(input, false);
|
||||||
|
|
||||||
|
trace!(
|
||||||
|
"Tokens: {:?}",
|
||||||
|
tokens.clone().collect::<Result<Vec<_>, _>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
match parser.parse(tokens) {
|
||||||
|
Ok(val) => Ok(val),
|
||||||
|
Err(err) => Err(ShellError::parse_error(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn parse_module(input: &str) -> Result<Module, ShellError> {
|
||||||
|
let _ = pretty_env_logger::try_init();
|
||||||
|
|
||||||
|
let parser = ModuleParser::new();
|
||||||
let tokens = Lexer::new(input, false);
|
let tokens = Lexer::new(input, false);
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
|
@ -62,6 +81,44 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(parsed, expected);
|
assert_eq!(parsed, expected);
|
||||||
assert_eq!(printed, source);
|
assert_eq!(printed, source);
|
||||||
|
|
||||||
|
let span = expected.span;
|
||||||
|
|
||||||
|
let expected_module = ModuleBuilder::spanned_items(
|
||||||
|
vec![Spanned::from_item(RawItem::Expression(expected), span)],
|
||||||
|
span.start,
|
||||||
|
span.end,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_parse_module(source, expected_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_parse_module(source: &str, expected: Module) {
|
||||||
|
let parsed = match parse_module(source) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(ShellError::Diagnostic(diag)) => {
|
||||||
|
use language_reporting::termcolor;
|
||||||
|
|
||||||
|
let writer = termcolor::StandardStream::stdout(termcolor::ColorChoice::Auto);
|
||||||
|
let files = crate::parser::span::Files::new(source.to_string());
|
||||||
|
|
||||||
|
language_reporting::emit(
|
||||||
|
&mut writer.lock(),
|
||||||
|
&files,
|
||||||
|
&diag.diagnostic,
|
||||||
|
&language_reporting::DefaultConfig,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
panic!("Test failed")
|
||||||
|
}
|
||||||
|
Err(err) => panic!("Something went wrong during parse: {:#?}", err),
|
||||||
|
};
|
||||||
|
|
||||||
|
let printed = parsed.print();
|
||||||
|
|
||||||
|
assert_eq!(parsed, expected);
|
||||||
|
assert_eq!(printed, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! commands {
|
macro_rules! commands {
|
||||||
|
@ -214,4 +271,8 @@ mod tests {
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::parser::ast::{ModuleBuilder, RawItem};
|
||||||
|
use crate::parser::lexer::Spanned;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,894 +1,16 @@
|
||||||
use crate::parser::lexer::{Span, Spanned};
|
crate mod expression;
|
||||||
use crate::prelude::*;
|
crate mod expression_builder;
|
||||||
use adhoc_derive::FromStr;
|
crate mod module;
|
||||||
use derive_new::new;
|
crate mod module_builder;
|
||||||
use getset::Getters;
|
crate mod parser_utils;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
use std::io::Write;
|
crate use expression::{
|
||||||
use std::str::FromStr;
|
Bare, Binary, Block, Call, Expression, Flag, Leaf, Operator, ParameterIdentifier,
|
||||||
|
Parenthesized, Path, Pipeline, RawExpression, Unit, Variable,
|
||||||
#[derive(new)]
|
};
|
||||||
pub struct ExpressionBuilder {
|
crate use expression_builder::ExpressionBuilder;
|
||||||
#[new(default)]
|
crate use module::{Module};
|
||||||
pos: usize,
|
crate use module_builder::ModuleBuilder;
|
||||||
}
|
|
||||||
|
#[cfg(test)]
|
||||||
#[allow(unused)]
|
crate use module::RawItem;
|
||||||
impl ExpressionBuilder {
|
|
||||||
pub fn op(&mut self, input: impl Into<Operator>) -> Spanned<Operator> {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
let (start, end) = self.consume(input.as_str());
|
|
||||||
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_op(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_op(input: impl Into<Operator>, start: usize, end: usize) -> Spanned<Operator> {
|
|
||||||
Spanned {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
item: input.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn string(&mut self, input: impl Into<String>) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
let (start, _) = self.consume("\"");
|
|
||||||
self.consume(&input);
|
|
||||||
let (_, end) = self.consume("\"");
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_string(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_string(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Leaf(Leaf::String(input)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bare(&mut self, input: impl Into<Bare>) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
let (start, end) = self.consume(&input.body);
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_bare(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_bare(input: impl Into<Bare>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Leaf(Leaf::Bare(input)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn boolean(&mut self, input: impl Into<bool>) -> Expression {
|
|
||||||
let boolean = input.into();
|
|
||||||
|
|
||||||
let (start, end) = match boolean {
|
|
||||||
true => self.consume("$yes"),
|
|
||||||
false => self.consume("$no"),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_boolean(boolean, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_boolean(input: impl Into<bool>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Leaf(Leaf::Boolean(input)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn int(&mut self, input: impl Into<i64>) -> Expression {
|
|
||||||
let int = input.into();
|
|
||||||
|
|
||||||
let (start, end) = self.consume(&int.to_string());
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_int(int, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_int(input: impl Into<i64>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Leaf(Leaf::Int(input)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unit(&mut self, input: (impl Into<i64>, impl Into<Unit>)) -> Expression {
|
|
||||||
let (int, unit) = (input.0.into(), input.1.into());
|
|
||||||
|
|
||||||
let (start, _) = self.consume(&int.to_string());
|
|
||||||
let (_, end) = self.consume(&unit.to_string());
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_unit((int, unit), start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_unit(
|
|
||||||
input: (impl Into<i64>, impl Into<Unit>),
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
) -> Expression {
|
|
||||||
let (int, unit) = (input.0.into(), input.1.into());
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Leaf(Leaf::Unit(int, unit)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn flag(&mut self, input: impl Into<String>) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
let (start, _) = self.consume("--");
|
|
||||||
let (_, end) = self.consume(&input);
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_flag(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_flag(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Flag(Flag::Longhand(input)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shorthand(&mut self, input: impl Into<String>) -> Expression {
|
|
||||||
let int = input.into();
|
|
||||||
|
|
||||||
let size = int.to_string().len();
|
|
||||||
|
|
||||||
let start = self.pos;
|
|
||||||
let end = self.pos + size + 1;
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_shorthand(int, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_shorthand(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Flag(Flag::Shorthand(input)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parens(
|
|
||||||
&mut self,
|
|
||||||
input: impl FnOnce(&mut ExpressionBuilder) -> Expression,
|
|
||||||
) -> Expression {
|
|
||||||
let (start, _) = self.consume("(");
|
|
||||||
let input = input(self);
|
|
||||||
let (_, end) = self.consume(")");
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_parens(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_parens(input: Expression, start: usize, end: usize) -> Expression {
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Parenthesized(Box::new(Parenthesized::new(input))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn block(&mut self, input: &dyn Fn(&mut ExpressionBuilder) -> Expression) -> Expression {
|
|
||||||
let (start, _) = self.consume("{ ");
|
|
||||||
let input = input(self);
|
|
||||||
let (_, end) = self.consume(" }");
|
|
||||||
self.pos = end;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_block(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_block(input: Expression, start: usize, end: usize) -> Expression {
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Block(Box::new(Block::new(input))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn binary(
|
|
||||||
&mut self,
|
|
||||||
input: (
|
|
||||||
&dyn Fn(&mut ExpressionBuilder) -> Expression,
|
|
||||||
&dyn Fn(&mut ExpressionBuilder) -> Spanned<Operator>,
|
|
||||||
&dyn Fn(&mut ExpressionBuilder) -> Expression,
|
|
||||||
),
|
|
||||||
) -> Expression {
|
|
||||||
let start = self.pos;
|
|
||||||
|
|
||||||
let left = (input.0)(self);
|
|
||||||
self.consume(" ");
|
|
||||||
let operator = (input.1)(self);
|
|
||||||
self.consume(" ");
|
|
||||||
let right = (input.2)(self);
|
|
||||||
|
|
||||||
let end = self.pos;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_binary((left, operator, right), start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_binary(
|
|
||||||
input: (
|
|
||||||
impl Into<Expression>,
|
|
||||||
impl Into<Spanned<Operator>>,
|
|
||||||
impl Into<Expression>,
|
|
||||||
),
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
) -> Expression {
|
|
||||||
let binary = Binary::new(input.0, input.1.into(), input.2);
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Binary(Box::new(binary)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn path(
|
|
||||||
&mut self,
|
|
||||||
input: (
|
|
||||||
&dyn Fn(&mut ExpressionBuilder) -> Expression,
|
|
||||||
Vec<impl Into<String>>,
|
|
||||||
),
|
|
||||||
) -> Expression {
|
|
||||||
let start = self.pos;
|
|
||||||
|
|
||||||
let head = (input.0)(self);
|
|
||||||
|
|
||||||
let mut tail = vec![];
|
|
||||||
|
|
||||||
for item in input.1 {
|
|
||||||
self.consume(".");
|
|
||||||
let item = item.into();
|
|
||||||
let (start, end) = self.consume(&item);
|
|
||||||
tail.push(Spanned::new(Span::from((start, end)), item));
|
|
||||||
}
|
|
||||||
|
|
||||||
let end = self.pos;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_path((head, tail), start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_path(
|
|
||||||
input: (impl Into<Expression>, Vec<Spanned<String>>),
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
) -> Expression {
|
|
||||||
let path = Path::new(input.0.into(), input.1);
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Path(Box::new(path)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn call(
|
|
||||||
&mut self,
|
|
||||||
input: (
|
|
||||||
&(dyn Fn(&mut ExpressionBuilder) -> Expression),
|
|
||||||
Vec<&dyn Fn(&mut ExpressionBuilder) -> Expression>,
|
|
||||||
),
|
|
||||||
) -> Expression {
|
|
||||||
let start = self.pos;
|
|
||||||
|
|
||||||
let name = (&input.0)(self);
|
|
||||||
|
|
||||||
let mut args = vec![];
|
|
||||||
|
|
||||||
for item in input.1 {
|
|
||||||
self.consume(" ");
|
|
||||||
args.push(item(self));
|
|
||||||
}
|
|
||||||
|
|
||||||
let end = self.pos;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_call((name, args), start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_call(input: impl Into<Call>, start: usize, end: usize) -> Expression {
|
|
||||||
let call = input.into();
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr: RawExpression::Call(Box::new(call)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn var(&mut self, input: impl Into<String>) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
let (start, _) = self.consume("$");
|
|
||||||
let (_, end) = self.consume(&input);
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_var(input, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_var(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
|
||||||
let input = input.into();
|
|
||||||
|
|
||||||
let expr = match &input[..] {
|
|
||||||
"it" => RawExpression::VariableReference(Variable::It),
|
|
||||||
_ => RawExpression::VariableReference(Variable::Other(input)),
|
|
||||||
};
|
|
||||||
|
|
||||||
Expression {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
expr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pipeline(
|
|
||||||
&mut self,
|
|
||||||
input: Vec<&dyn Fn(&mut ExpressionBuilder) -> Expression>,
|
|
||||||
) -> Pipeline {
|
|
||||||
let start = self.pos;
|
|
||||||
|
|
||||||
let mut exprs = vec![];
|
|
||||||
let mut input = input.into_iter();
|
|
||||||
|
|
||||||
let next = input.next().unwrap();
|
|
||||||
exprs.push(next(self));
|
|
||||||
|
|
||||||
for item in input {
|
|
||||||
self.consume(" | ");
|
|
||||||
exprs.push(item(self));
|
|
||||||
}
|
|
||||||
|
|
||||||
let end = self.pos;
|
|
||||||
|
|
||||||
ExpressionBuilder::spanned_pipeline(exprs, start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spanned_pipeline(input: Vec<Expression>, start: usize, end: usize) -> Pipeline {
|
|
||||||
Pipeline {
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
commands: input,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sp(&mut self) {
|
|
||||||
self.consume(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ws(&mut self, input: &str) {
|
|
||||||
self.consume(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn consume(&mut self, input: &str) -> (usize, usize) {
|
|
||||||
let start = self.pos;
|
|
||||||
self.pos += input.len();
|
|
||||||
(start, self.pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
|
|
||||||
pub enum Operator {
|
|
||||||
Equal,
|
|
||||||
NotEqual,
|
|
||||||
LessThan,
|
|
||||||
GreaterThan,
|
|
||||||
LessThanOrEqual,
|
|
||||||
GreaterThanOrEqual,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Operator {
|
|
||||||
pub fn print(&self) -> String {
|
|
||||||
self.as_str().to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_str(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
Operator::Equal => "==",
|
|
||||||
Operator::NotEqual => "!=",
|
|
||||||
Operator::LessThan => "<",
|
|
||||||
Operator::GreaterThan => ">",
|
|
||||||
Operator::LessThanOrEqual => "<=",
|
|
||||||
Operator::GreaterThanOrEqual => ">=",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for Operator {
|
|
||||||
fn from(input: &str) -> Operator {
|
|
||||||
Operator::from_str(input).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Operator {
|
|
||||||
type Err = ();
|
|
||||||
fn from_str(input: &str) -> Result<Self, <Self as std::str::FromStr>::Err> {
|
|
||||||
match input {
|
|
||||||
"==" => Ok(Operator::Equal),
|
|
||||||
"!=" => Ok(Operator::NotEqual),
|
|
||||||
"<" => Ok(Operator::LessThan),
|
|
||||||
">" => Ok(Operator::GreaterThan),
|
|
||||||
"<=" => Ok(Operator::LessThanOrEqual),
|
|
||||||
">=" => Ok(Operator::GreaterThanOrEqual),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
pub struct Expression {
|
|
||||||
crate expr: RawExpression,
|
|
||||||
crate span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::Deref for Expression {
|
|
||||||
type Target = RawExpression;
|
|
||||||
|
|
||||||
fn deref(&self) -> &RawExpression {
|
|
||||||
&self.expr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Expression {
|
|
||||||
crate fn print(&self) -> String {
|
|
||||||
self.expr.print()
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn as_external_arg(&self) -> String {
|
|
||||||
self.expr.as_external_arg()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
pub enum RawExpression {
|
|
||||||
Leaf(Leaf),
|
|
||||||
Flag(Flag),
|
|
||||||
Parenthesized(Box<Parenthesized>),
|
|
||||||
Block(Box<Block>),
|
|
||||||
Binary(Box<Binary>),
|
|
||||||
Path(Box<Path>),
|
|
||||||
Call(Box<Call>),
|
|
||||||
VariableReference(Variable),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RawExpression {
|
|
||||||
// crate fn leaf(leaf: impl Into<Leaf>) -> Expression {
|
|
||||||
// Expression::Leaf(leaf.into())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// crate fn flag(flag: impl Into<Flag>) -> Expression {
|
|
||||||
// Expression::Flag(flag.into())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// crate fn call(head: Expression, tail: Vec<Expression>) -> Expression {
|
|
||||||
// if tail.len() == 0 {
|
|
||||||
// Expression::Call(Box::new(ParsedCommand::new(head.into(), None)))
|
|
||||||
// } else {
|
|
||||||
// Expression::Call(Box::new(ParsedCommand::new(head.into(), Some(tail))))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// crate fn binary(
|
|
||||||
// left: impl Into<Expression>,
|
|
||||||
// operator: impl Into<Operator>,
|
|
||||||
// right: impl Into<Expression>,
|
|
||||||
// ) -> Expression {
|
|
||||||
// Expression::Binary(Box::new(Binary {
|
|
||||||
// left: left.into(),
|
|
||||||
// operator: operator.into(),
|
|
||||||
// right: right.into(),
|
|
||||||
// }))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// crate fn block(expr: impl Into<Expression>) -> Expression {
|
|
||||||
// Expression::Block(Box::new(Block::new(expr.into())))
|
|
||||||
// }
|
|
||||||
|
|
||||||
crate fn print(&self) -> String {
|
|
||||||
match self {
|
|
||||||
RawExpression::Call(c) => c.print(),
|
|
||||||
RawExpression::Leaf(l) => l.print(),
|
|
||||||
RawExpression::Flag(f) => f.print(),
|
|
||||||
RawExpression::Parenthesized(p) => p.print(),
|
|
||||||
RawExpression::Block(b) => b.print(),
|
|
||||||
RawExpression::VariableReference(r) => r.print(),
|
|
||||||
RawExpression::Path(p) => p.print(),
|
|
||||||
RawExpression::Binary(b) => b.print(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn as_external_arg(&self) -> String {
|
|
||||||
match self {
|
|
||||||
RawExpression::Call(c) => c.as_external_arg(),
|
|
||||||
RawExpression::Leaf(l) => l.as_external_arg(),
|
|
||||||
RawExpression::Flag(f) => f.as_external_arg(),
|
|
||||||
RawExpression::Parenthesized(p) => p.as_external_arg(),
|
|
||||||
RawExpression::Block(b) => b.as_external_arg(),
|
|
||||||
RawExpression::VariableReference(r) => r.as_external_arg(),
|
|
||||||
RawExpression::Path(p) => p.as_external_arg(),
|
|
||||||
RawExpression::Binary(b) => b.as_external_arg(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn as_string(&self) -> Option<String> {
|
|
||||||
match self {
|
|
||||||
RawExpression::Leaf(Leaf::String(s)) => Some(s.clone()),
|
|
||||||
RawExpression::Leaf(Leaf::Bare(path)) => Some(path.to_string()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
crate fn as_bare(&self) -> Option<String> {
|
|
||||||
match self {
|
|
||||||
RawExpression::Leaf(Leaf::Bare(p)) => Some(p.to_string()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
crate fn as_block(&self) -> Option<Block> {
|
|
||||||
match self {
|
|
||||||
RawExpression::Block(block) => Some(*block.clone()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn is_flag(&self, value: &str) -> bool {
|
|
||||||
match self {
|
|
||||||
RawExpression::Flag(Flag::Longhand(f)) if value == f => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
|
||||||
pub struct Block {
|
|
||||||
crate expr: Expression,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Block {
|
|
||||||
fn print(&self) -> String {
|
|
||||||
format!("{{ {} }}", self.expr.print())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_external_arg(&self) -> String {
|
|
||||||
format!("{{ {} }}", self.expr.as_external_arg())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
|
||||||
pub struct Parenthesized {
|
|
||||||
crate expr: Expression,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parenthesized {
|
|
||||||
fn print(&self) -> String {
|
|
||||||
format!("({})", self.expr.print())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_external_arg(&self) -> String {
|
|
||||||
format!("({})", self.expr.as_external_arg())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Getters, new)]
|
|
||||||
pub struct Path {
|
|
||||||
#[get = "crate"]
|
|
||||||
head: Expression,
|
|
||||||
|
|
||||||
#[get = "crate"]
|
|
||||||
tail: Vec<Spanned<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Path {
|
|
||||||
crate fn print(&self) -> String {
|
|
||||||
let mut out = self.head.print();
|
|
||||||
|
|
||||||
for item in self.tail.iter() {
|
|
||||||
out.push_str(&format!(".{}", item.item));
|
|
||||||
}
|
|
||||||
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn as_external_arg(&self) -> String {
|
|
||||||
let mut out = self.head.as_external_arg();
|
|
||||||
|
|
||||||
for item in self.tail.iter() {
|
|
||||||
out.push_str(&format!(".{}", item.item));
|
|
||||||
}
|
|
||||||
|
|
||||||
out
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
pub enum Variable {
|
|
||||||
It,
|
|
||||||
Other(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Variable {
|
|
||||||
fn print(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Variable::It => format!("$it"),
|
|
||||||
Variable::Other(s) => format!("${}", s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_external_arg(&self) -> String {
|
|
||||||
self.print()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
|
||||||
pub struct Bare {
|
|
||||||
body: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for Bare {
|
|
||||||
fn from(input: String) -> Bare {
|
|
||||||
Bare { body: input }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for Bare {
|
|
||||||
fn from(input: &str) -> Bare {
|
|
||||||
Bare {
|
|
||||||
body: input.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Bare {
|
|
||||||
crate fn from_string(string: impl Into<String>) -> Bare {
|
|
||||||
Bare {
|
|
||||||
body: string.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn to_string(&self) -> String {
|
|
||||||
self.body.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, FromStr)]
|
|
||||||
pub enum Unit {
|
|
||||||
#[adhoc(regex = "^B$")]
|
|
||||||
B,
|
|
||||||
#[adhoc(regex = "^KB$")]
|
|
||||||
KB,
|
|
||||||
#[adhoc(regex = "^MB$")]
|
|
||||||
MB,
|
|
||||||
#[adhoc(regex = "^GB$")]
|
|
||||||
GB,
|
|
||||||
#[adhoc(regex = "^TB$")]
|
|
||||||
TB,
|
|
||||||
#[adhoc(regex = "^PB$")]
|
|
||||||
PB,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for Unit {
|
|
||||||
fn from(input: &str) -> Unit {
|
|
||||||
Unit::from_str(input).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Unit {
|
|
||||||
crate fn compute(&self, size: i64) -> Value {
|
|
||||||
Value::int(match self {
|
|
||||||
Unit::B => size,
|
|
||||||
Unit::KB => size * 1024,
|
|
||||||
Unit::MB => size * 1024 * 1024,
|
|
||||||
Unit::GB => size * 1024 * 1024 * 1024,
|
|
||||||
Unit::TB => size * 1024 * 1024 * 1024 * 1024,
|
|
||||||
Unit::PB => size * 1024 * 1024 * 1024 * 1024 * 1024,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn to_string(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
Unit::B => "B",
|
|
||||||
Unit::KB => "KB",
|
|
||||||
Unit::MB => "MB",
|
|
||||||
Unit::GB => "GB",
|
|
||||||
Unit::TB => "TB",
|
|
||||||
Unit::PB => "PB",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
pub enum Leaf {
|
|
||||||
String(String),
|
|
||||||
Bare(Bare),
|
|
||||||
Boolean(bool),
|
|
||||||
Int(i64),
|
|
||||||
Unit(i64, Unit),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Leaf {
|
|
||||||
fn print(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Leaf::String(s) => format!("{:?}", s),
|
|
||||||
Leaf::Bare(path) => format!("{}", path.to_string()),
|
|
||||||
Leaf::Boolean(b) => format!("{}", b),
|
|
||||||
Leaf::Int(i) => format!("{}", i),
|
|
||||||
Leaf::Unit(i, unit) => format!("{}{:?}", i, unit),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_external_arg(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Leaf::String(s) => format!("\"{}\"", s),
|
|
||||||
Leaf::Bare(path) => path.to_string(),
|
|
||||||
Leaf::Boolean(b) => b.to_string(),
|
|
||||||
Leaf::Int(i) => i.to_string(),
|
|
||||||
Leaf::Unit(i, unit) => format!("{}{:?}", i, unit),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
pub struct Binary {
|
|
||||||
crate left: Expression,
|
|
||||||
crate operator: Spanned<Operator>,
|
|
||||||
crate right: Expression,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Binary {
|
|
||||||
crate fn new(
|
|
||||||
left: impl Into<Expression>,
|
|
||||||
operator: Spanned<Operator>,
|
|
||||||
right: impl Into<Expression>,
|
|
||||||
) -> Binary {
|
|
||||||
Binary {
|
|
||||||
left: left.into(),
|
|
||||||
operator,
|
|
||||||
right: right.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Binary {
|
|
||||||
fn print(&self) -> String {
|
|
||||||
format!(
|
|
||||||
"{} {} {}",
|
|
||||||
self.left.print(),
|
|
||||||
self.operator.print(),
|
|
||||||
self.right.print()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_external_arg(&self) -> String {
|
|
||||||
format!(
|
|
||||||
"{} {} {}",
|
|
||||||
self.left.as_external_arg(),
|
|
||||||
self.operator.print(),
|
|
||||||
self.right.as_external_arg()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
|
||||||
pub enum Flag {
|
|
||||||
Shorthand(String),
|
|
||||||
Longhand(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Flag {
|
|
||||||
#[allow(unused)]
|
|
||||||
crate fn print(&self) -> String {
|
|
||||||
match self {
|
|
||||||
Flag::Shorthand(s) => format!("-{}", s),
|
|
||||||
Flag::Longhand(s) => format!("--{}", s),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
crate fn as_external_arg(&self) -> String {
|
|
||||||
self.print()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
|
||||||
pub struct Call {
|
|
||||||
crate name: Expression,
|
|
||||||
crate args: Option<Vec<Expression>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(Expression, Vec<Expression>)> for Call {
|
|
||||||
fn from(input: (Expression, Vec<Expression>)) -> Call {
|
|
||||||
Call {
|
|
||||||
name: input.0,
|
|
||||||
args: if input.1.len() == 0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(input.1)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Expression> for Call {
|
|
||||||
fn from(input: Expression) -> Call {
|
|
||||||
Call {
|
|
||||||
name: input,
|
|
||||||
args: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Call {
|
|
||||||
fn as_external_arg(&self) -> String {
|
|
||||||
let mut out = vec![];
|
|
||||||
|
|
||||||
write!(out, "{}", self.name.as_external_arg()).unwrap();
|
|
||||||
|
|
||||||
if let Some(args) = &self.args {
|
|
||||||
for arg in args.iter() {
|
|
||||||
write!(out, " {}", arg.as_external_arg()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String::from_utf8_lossy(&out).into_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print(&self) -> String {
|
|
||||||
let mut out = vec![];
|
|
||||||
|
|
||||||
write!(out, "{}", self.name.print()).unwrap();
|
|
||||||
|
|
||||||
if let Some(args) = &self.args {
|
|
||||||
for arg in args.iter() {
|
|
||||||
write!(out, " {}", arg.print()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String::from_utf8_lossy(&out).into_owned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(new, Debug, Eq, PartialEq)]
|
|
||||||
pub struct Pipeline {
|
|
||||||
crate commands: Vec<Expression>,
|
|
||||||
crate span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pipeline {
|
|
||||||
crate fn from_parts(
|
|
||||||
command: Expression,
|
|
||||||
rest: Vec<Expression>,
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
) -> Pipeline {
|
|
||||||
let mut commands = vec![command];
|
|
||||||
commands.extend(rest);
|
|
||||||
|
|
||||||
Pipeline {
|
|
||||||
commands,
|
|
||||||
span: Span::from((start, end)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
crate fn print(&self) -> String {
|
|
||||||
itertools::join(self.commands.iter().map(|i| i.print()), " | ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
541
src/parser/ast/expression.rs
Normal file
541
src/parser/ast/expression.rs
Normal file
|
@ -0,0 +1,541 @@
|
||||||
|
use crate::parser::lexer::{Span, Spanned};
|
||||||
|
use crate::prelude::*;
|
||||||
|
use adhoc_derive::FromStr;
|
||||||
|
use derive_new::new;
|
||||||
|
use getset::Getters;
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use std::io::Write;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
|
||||||
|
pub enum Operator {
|
||||||
|
Equal,
|
||||||
|
NotEqual,
|
||||||
|
LessThan,
|
||||||
|
GreaterThan,
|
||||||
|
LessThanOrEqual,
|
||||||
|
GreaterThanOrEqual,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Operator {
|
||||||
|
pub fn print(&self) -> String {
|
||||||
|
self.as_str().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
Operator::Equal => "==",
|
||||||
|
Operator::NotEqual => "!=",
|
||||||
|
Operator::LessThan => "<",
|
||||||
|
Operator::GreaterThan => ">",
|
||||||
|
Operator::LessThanOrEqual => "<=",
|
||||||
|
Operator::GreaterThanOrEqual => ">=",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Operator {
|
||||||
|
fn from(input: &str) -> Operator {
|
||||||
|
Operator::from_str(input).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Operator {
|
||||||
|
type Err = ();
|
||||||
|
fn from_str(input: &str) -> Result<Self, <Self as std::str::FromStr>::Err> {
|
||||||
|
match input {
|
||||||
|
"==" => Ok(Operator::Equal),
|
||||||
|
"!=" => Ok(Operator::NotEqual),
|
||||||
|
"<" => Ok(Operator::LessThan),
|
||||||
|
">" => Ok(Operator::GreaterThan),
|
||||||
|
"<=" => Ok(Operator::LessThanOrEqual),
|
||||||
|
">=" => Ok(Operator::GreaterThanOrEqual),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub struct Expression {
|
||||||
|
crate expr: RawExpression,
|
||||||
|
crate span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for Expression {
|
||||||
|
type Target = RawExpression;
|
||||||
|
|
||||||
|
fn deref(&self) -> &RawExpression {
|
||||||
|
&self.expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Expression {
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
self.expr.print()
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn as_external_arg(&self) -> String {
|
||||||
|
self.expr.as_external_arg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub enum RawExpression {
|
||||||
|
Leaf(Leaf),
|
||||||
|
Flag(Flag),
|
||||||
|
Parenthesized(Box<Parenthesized>),
|
||||||
|
Block(Box<Block>),
|
||||||
|
Binary(Box<Binary>),
|
||||||
|
Path(Box<Path>),
|
||||||
|
Call(Box<Call>),
|
||||||
|
VariableReference(Variable),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawExpression {
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
RawExpression::Call(c) => c.print(),
|
||||||
|
RawExpression::Leaf(l) => l.print(),
|
||||||
|
RawExpression::Flag(f) => f.print(),
|
||||||
|
RawExpression::Parenthesized(p) => p.print(),
|
||||||
|
RawExpression::Block(b) => b.print(),
|
||||||
|
RawExpression::VariableReference(r) => r.print(),
|
||||||
|
RawExpression::Path(p) => p.print(),
|
||||||
|
RawExpression::Binary(b) => b.print(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn as_external_arg(&self) -> String {
|
||||||
|
match self {
|
||||||
|
RawExpression::Call(c) => c.as_external_arg(),
|
||||||
|
RawExpression::Leaf(l) => l.as_external_arg(),
|
||||||
|
RawExpression::Flag(f) => f.as_external_arg(),
|
||||||
|
RawExpression::Parenthesized(p) => p.as_external_arg(),
|
||||||
|
RawExpression::Block(b) => b.as_external_arg(),
|
||||||
|
RawExpression::VariableReference(r) => r.as_external_arg(),
|
||||||
|
RawExpression::Path(p) => p.as_external_arg(),
|
||||||
|
RawExpression::Binary(b) => b.as_external_arg(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn as_string(&self) -> Option<String> {
|
||||||
|
match self {
|
||||||
|
RawExpression::Leaf(Leaf::String(s)) => Some(s.to_string()),
|
||||||
|
RawExpression::Leaf(Leaf::Bare(path)) => Some(path.to_string()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn as_bare(&self) -> Option<String> {
|
||||||
|
match self {
|
||||||
|
RawExpression::Leaf(Leaf::Bare(p)) => Some(p.to_string()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn as_block(&self) -> Option<Block> {
|
||||||
|
match self {
|
||||||
|
RawExpression::Block(block) => Some(*block.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn is_flag(&self, value: &str) -> bool {
|
||||||
|
match self {
|
||||||
|
RawExpression::Flag(Flag::Longhand(f)) if value == f => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
||||||
|
pub struct Block {
|
||||||
|
crate expr: Expression,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Block {
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
format!("{{ {} }}", self.expr.print())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_external_arg(&self) -> String {
|
||||||
|
format!("{{ {} }}", self.expr.as_external_arg())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
||||||
|
pub struct Parenthesized {
|
||||||
|
crate expr: Expression,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parenthesized {
|
||||||
|
fn print(&self) -> String {
|
||||||
|
format!("({})", self.expr.print())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_external_arg(&self) -> String {
|
||||||
|
format!("({})", self.expr.as_external_arg())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Getters, new)]
|
||||||
|
pub struct Path {
|
||||||
|
#[get = "crate"]
|
||||||
|
head: Expression,
|
||||||
|
|
||||||
|
#[get = "crate"]
|
||||||
|
tail: Vec<Spanned<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Path {
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
let mut out = self.head.print();
|
||||||
|
|
||||||
|
for item in self.tail.iter() {
|
||||||
|
out.push_str(&format!(".{}", item.item));
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn as_external_arg(&self) -> String {
|
||||||
|
let mut out = self.head.as_external_arg();
|
||||||
|
|
||||||
|
for item in self.tail.iter() {
|
||||||
|
out.push_str(&format!(".{}", item.item));
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub enum Variable {
|
||||||
|
It,
|
||||||
|
Other(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Variable {
|
||||||
|
crate fn from_string(s: &str) -> Variable {
|
||||||
|
match s {
|
||||||
|
"it" => ast::Variable::It,
|
||||||
|
_ => ast::Variable::Other(s.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Variable::It => format!("$it"),
|
||||||
|
Variable::Other(s) => format!("${}", s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_external_arg(&self) -> String {
|
||||||
|
self.print()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new, Getters)]
|
||||||
|
pub struct Bare {
|
||||||
|
#[get = "crate"]
|
||||||
|
body: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Bare {
|
||||||
|
fn from(input: String) -> Bare {
|
||||||
|
Bare { body: input }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Bare {
|
||||||
|
fn from(input: &str) -> Bare {
|
||||||
|
Bare {
|
||||||
|
body: input.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bare {
|
||||||
|
crate fn from_string(string: impl Into<String>) -> Bare {
|
||||||
|
Bare {
|
||||||
|
body: string.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn to_string(&self) -> String {
|
||||||
|
self.body.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, FromStr)]
|
||||||
|
pub enum Unit {
|
||||||
|
#[adhoc(regex = "^B$")]
|
||||||
|
B,
|
||||||
|
#[adhoc(regex = "^KB$")]
|
||||||
|
KB,
|
||||||
|
#[adhoc(regex = "^MB$")]
|
||||||
|
MB,
|
||||||
|
#[adhoc(regex = "^GB$")]
|
||||||
|
GB,
|
||||||
|
#[adhoc(regex = "^TB$")]
|
||||||
|
TB,
|
||||||
|
#[adhoc(regex = "^PB$")]
|
||||||
|
PB,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Unit {
|
||||||
|
fn from(input: &str) -> Unit {
|
||||||
|
Unit::from_str(input).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unit {
|
||||||
|
crate fn compute(&self, size: i64) -> Value {
|
||||||
|
Value::int(match self {
|
||||||
|
Unit::B => size,
|
||||||
|
Unit::KB => size * 1024,
|
||||||
|
Unit::MB => size * 1024 * 1024,
|
||||||
|
Unit::GB => size * 1024 * 1024 * 1024,
|
||||||
|
Unit::TB => size * 1024 * 1024 * 1024 * 1024,
|
||||||
|
Unit::PB => size * 1024 * 1024 * 1024 * 1024 * 1024,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn to_string(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Unit::B => "B",
|
||||||
|
Unit::KB => "KB",
|
||||||
|
Unit::MB => "MB",
|
||||||
|
Unit::GB => "GB",
|
||||||
|
Unit::TB => "TB",
|
||||||
|
Unit::PB => "PB",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub enum RawParameterIdentifier {
|
||||||
|
#[allow(unused)]
|
||||||
|
Bare(Spanned<Bare>),
|
||||||
|
Var(Spanned<Variable>),
|
||||||
|
ShorthandFlag(Spanned<String>),
|
||||||
|
LonghandFlag(Spanned<String>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawParameterIdentifier {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
RawParameterIdentifier::Bare(b) => b.to_string(),
|
||||||
|
RawParameterIdentifier::Var(v) => v.print(),
|
||||||
|
RawParameterIdentifier::ShorthandFlag(f) => f.to_string(),
|
||||||
|
RawParameterIdentifier::LonghandFlag(f) => f.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ParameterIdentifier = Spanned<RawParameterIdentifier>;
|
||||||
|
|
||||||
|
impl ParameterIdentifier {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn bare(bare: Spanned<Bare>, span: impl Into<Span>) -> ParameterIdentifier {
|
||||||
|
let id = RawParameterIdentifier::Bare(bare);
|
||||||
|
Spanned::from_item(id, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn var(var: Spanned<Variable>, span: impl Into<Span>) -> ParameterIdentifier {
|
||||||
|
let id = RawParameterIdentifier::Var(var);
|
||||||
|
Spanned::from_item(id, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flag(flag: Spanned<String>, span: impl Into<Span>) -> ParameterIdentifier {
|
||||||
|
let id = RawParameterIdentifier::LonghandFlag(flag);
|
||||||
|
Spanned::from_item(id, span)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shorthand(flag: Spanned<String>, span: impl Into<Span>) -> ParameterIdentifier {
|
||||||
|
let id = RawParameterIdentifier::ShorthandFlag(flag);
|
||||||
|
Spanned::from_item(id, span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub enum Leaf {
|
||||||
|
String(String),
|
||||||
|
Bare(Bare),
|
||||||
|
Boolean(bool),
|
||||||
|
Int(i64),
|
||||||
|
Unit(i64, Unit),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Leaf {
|
||||||
|
fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Leaf::String(s) => format!("{:?}", s),
|
||||||
|
Leaf::Bare(path) => format!("{}", path.to_string()),
|
||||||
|
Leaf::Boolean(b) => format!("{}", b),
|
||||||
|
Leaf::Int(i) => format!("{}", i),
|
||||||
|
Leaf::Unit(i, unit) => format!("{}{:?}", i, unit),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_external_arg(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Leaf::String(s) => format!("\"{}\"", s),
|
||||||
|
Leaf::Bare(path) => format!("{}", path.to_string()),
|
||||||
|
Leaf::Boolean(b) => format!("{}", b),
|
||||||
|
Leaf::Int(i) => format!("{}", i),
|
||||||
|
Leaf::Unit(i, unit) => format!("{}{:?}", i, unit),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub struct Binary {
|
||||||
|
crate left: Expression,
|
||||||
|
crate operator: Spanned<Operator>,
|
||||||
|
crate right: Expression,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Binary {
|
||||||
|
crate fn new(
|
||||||
|
left: impl Into<Expression>,
|
||||||
|
operator: Spanned<Operator>,
|
||||||
|
right: impl Into<Expression>,
|
||||||
|
) -> Binary {
|
||||||
|
Binary {
|
||||||
|
left: left.into(),
|
||||||
|
operator,
|
||||||
|
right: right.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Binary {
|
||||||
|
fn print(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"{} {} {}",
|
||||||
|
self.left.print(),
|
||||||
|
self.operator.print(),
|
||||||
|
self.right.print()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_external_arg(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"{} {} {}",
|
||||||
|
self.left.as_external_arg(),
|
||||||
|
self.operator.print(),
|
||||||
|
self.right.as_external_arg()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||||
|
pub enum Flag {
|
||||||
|
Shorthand(String),
|
||||||
|
Longhand(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flag {
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Flag::Shorthand(s) => format!("-{}", s),
|
||||||
|
Flag::Longhand(s) => format!("--{}", s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn as_external_arg(&self) -> String {
|
||||||
|
self.print()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, new)]
|
||||||
|
pub struct Call {
|
||||||
|
crate name: Expression,
|
||||||
|
crate args: Option<Vec<Expression>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Expression, Vec<Expression>)> for Call {
|
||||||
|
fn from(input: (Expression, Vec<Expression>)) -> Call {
|
||||||
|
Call {
|
||||||
|
name: input.0,
|
||||||
|
args: if input.1.len() == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(input.1)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Expression> for Call {
|
||||||
|
fn from(input: Expression) -> Call {
|
||||||
|
Call {
|
||||||
|
name: input,
|
||||||
|
args: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Call {
|
||||||
|
fn as_external_arg(&self) -> String {
|
||||||
|
let mut out = vec![];
|
||||||
|
|
||||||
|
write!(out, "{}", self.name.as_external_arg()).unwrap();
|
||||||
|
|
||||||
|
if let Some(args) = &self.args {
|
||||||
|
for arg in args.iter() {
|
||||||
|
write!(out, " {}", arg.as_external_arg()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String::from_utf8_lossy(&out).into_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(&self) -> String {
|
||||||
|
let mut out = vec![];
|
||||||
|
|
||||||
|
write!(out, "{}", self.name.print()).unwrap();
|
||||||
|
|
||||||
|
if let Some(args) = &self.args {
|
||||||
|
for arg in args.iter() {
|
||||||
|
write!(out, " {}", arg.print()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String::from_utf8_lossy(&out).into_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(new, Debug, Eq, PartialEq, Clone)]
|
||||||
|
pub struct Pipeline {
|
||||||
|
crate commands: Vec<Expression>,
|
||||||
|
crate span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pipeline {
|
||||||
|
crate fn from_parts(
|
||||||
|
command: Expression,
|
||||||
|
rest: Vec<Expression>,
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> Pipeline {
|
||||||
|
let mut commands = vec![command];
|
||||||
|
commands.extend(rest);
|
||||||
|
|
||||||
|
Pipeline {
|
||||||
|
commands,
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
itertools::join(self.commands.iter().map(|i| i.print()), " | ")
|
||||||
|
}
|
||||||
|
}
|
401
src/parser/ast/expression_builder.rs
Normal file
401
src/parser/ast/expression_builder.rs
Normal file
|
@ -0,0 +1,401 @@
|
||||||
|
use crate::parser::lexer::{Span, Spanned};
|
||||||
|
use derive_new::new;
|
||||||
|
|
||||||
|
use crate::parser::ast::{self, Expression, RawExpression};
|
||||||
|
|
||||||
|
#[derive(new)]
|
||||||
|
pub struct ExpressionBuilder {
|
||||||
|
#[new(default)]
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
impl ExpressionBuilder {
|
||||||
|
pub fn op(&mut self, input: impl Into<ast::Operator>) -> Spanned<ast::Operator> {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
let (start, end) = self.consume(input.as_str());
|
||||||
|
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_op(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_op(
|
||||||
|
input: impl Into<ast::Operator>,
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> Spanned<ast::Operator> {
|
||||||
|
Spanned {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
item: input.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string(&mut self, input: impl Into<String>) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
let (start, _) = self.consume("\"");
|
||||||
|
self.consume(&input);
|
||||||
|
let (_, end) = self.consume("\"");
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_string(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_string(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Leaf(ast::Leaf::String(input)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bare(&mut self, input: impl Into<ast::Bare>) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
let (start, end) = self.consume(input.body());
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_bare(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_bare(input: impl Into<ast::Bare>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Leaf(ast::Leaf::Bare(input)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn boolean(&mut self, input: impl Into<bool>) -> Expression {
|
||||||
|
let boolean = input.into();
|
||||||
|
|
||||||
|
let (start, end) = match boolean {
|
||||||
|
true => self.consume("$yes"),
|
||||||
|
false => self.consume("$no"),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_boolean(boolean, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_boolean(input: impl Into<bool>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Leaf(ast::Leaf::Boolean(input)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn int(&mut self, input: impl Into<i64>) -> Expression {
|
||||||
|
let int = input.into();
|
||||||
|
|
||||||
|
let (start, end) = self.consume(&int.to_string());
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_int(int, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_int(input: impl Into<i64>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Leaf(ast::Leaf::Int(input)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unit(&mut self, input: (impl Into<i64>, impl Into<ast::Unit>)) -> Expression {
|
||||||
|
let (int, unit) = (input.0.into(), input.1.into());
|
||||||
|
|
||||||
|
let (start, _) = self.consume(&int.to_string());
|
||||||
|
let (_, end) = self.consume(&unit.to_string());
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_unit((int, unit), start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_unit(
|
||||||
|
input: (impl Into<i64>, impl Into<ast::Unit>),
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> Expression {
|
||||||
|
let (int, unit) = (input.0.into(), input.1.into());
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Leaf(ast::Leaf::Unit(int, unit)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flag(&mut self, input: impl Into<String>) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
let (start, _) = self.consume("--");
|
||||||
|
let (_, end) = self.consume(&input);
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_flag(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_flag(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Flag(ast::Flag::Longhand(input)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shorthand(&mut self, input: impl Into<String>) -> Expression {
|
||||||
|
let int = input.into();
|
||||||
|
|
||||||
|
let size = int.to_string().len();
|
||||||
|
|
||||||
|
let start = self.pos;
|
||||||
|
let end = self.pos + size + 1;
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_shorthand(int, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_shorthand(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Flag(ast::Flag::Shorthand(input)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parens(
|
||||||
|
&mut self,
|
||||||
|
input: impl FnOnce(&mut ExpressionBuilder) -> Expression,
|
||||||
|
) -> Expression {
|
||||||
|
let (start, _) = self.consume("(");
|
||||||
|
let input = input(self);
|
||||||
|
let (_, end) = self.consume(")");
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_parens(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_parens(input: Expression, start: usize, end: usize) -> Expression {
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Parenthesized(Box::new(ast::Parenthesized::new(input))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn raw_block(
|
||||||
|
&mut self,
|
||||||
|
input: &dyn Fn(&mut ExpressionBuilder) -> Expression,
|
||||||
|
) -> Spanned<ast::Block> {
|
||||||
|
let (start, _) = self.consume("{ ");
|
||||||
|
let input = input(self);
|
||||||
|
let (_, end) = self.consume(" }");
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_raw_block(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_raw_block(input: Expression, start: usize, end: usize) -> Spanned<ast::Block> {
|
||||||
|
Spanned::from_item(ast::Block::new(input), (start, end))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn block(&mut self, input: &dyn Fn(&mut ExpressionBuilder) -> Expression) -> Expression {
|
||||||
|
let (start, _) = self.consume("{ ");
|
||||||
|
let input = input(self);
|
||||||
|
let (_, end) = self.consume(" }");
|
||||||
|
self.pos = end;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_block(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_block(input: Expression, start: usize, end: usize) -> Expression {
|
||||||
|
let block = ast::Block::new(input);
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Block(Box::new(block)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn binary(
|
||||||
|
&mut self,
|
||||||
|
input: (
|
||||||
|
&dyn Fn(&mut ExpressionBuilder) -> Expression,
|
||||||
|
&dyn Fn(&mut ExpressionBuilder) -> Spanned<ast::Operator>,
|
||||||
|
&dyn Fn(&mut ExpressionBuilder) -> Expression,
|
||||||
|
),
|
||||||
|
) -> Expression {
|
||||||
|
let start = self.pos;
|
||||||
|
|
||||||
|
let left = (input.0)(self);
|
||||||
|
self.consume(" ");
|
||||||
|
let operator = (input.1)(self);
|
||||||
|
self.consume(" ");
|
||||||
|
let right = (input.2)(self);
|
||||||
|
|
||||||
|
let end = self.pos;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_binary((left, operator, right), start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_binary(
|
||||||
|
input: (
|
||||||
|
impl Into<Expression>,
|
||||||
|
impl Into<Spanned<ast::Operator>>,
|
||||||
|
impl Into<Expression>,
|
||||||
|
),
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> Expression {
|
||||||
|
let binary = ast::Binary::new(input.0, input.1.into(), input.2);
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Binary(Box::new(binary)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(
|
||||||
|
&mut self,
|
||||||
|
input: (
|
||||||
|
&dyn Fn(&mut ExpressionBuilder) -> Expression,
|
||||||
|
Vec<impl Into<String>>,
|
||||||
|
),
|
||||||
|
) -> Expression {
|
||||||
|
let start = self.pos;
|
||||||
|
|
||||||
|
let head = (input.0)(self);
|
||||||
|
|
||||||
|
let mut tail = vec![];
|
||||||
|
|
||||||
|
for item in input.1 {
|
||||||
|
self.consume(".");
|
||||||
|
let item = item.into();
|
||||||
|
let (start, end) = self.consume(&item);
|
||||||
|
tail.push(Spanned::new(Span::from((start, end)), item));
|
||||||
|
}
|
||||||
|
|
||||||
|
let end = self.pos;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_path((head, tail), start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_path(
|
||||||
|
input: (impl Into<Expression>, Vec<Spanned<String>>),
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> Expression {
|
||||||
|
let path = ast::Path::new(input.0.into(), input.1);
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Path(Box::new(path)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(
|
||||||
|
&mut self,
|
||||||
|
input: (
|
||||||
|
&(dyn Fn(&mut ExpressionBuilder) -> Expression),
|
||||||
|
Vec<&dyn Fn(&mut ExpressionBuilder) -> Expression>,
|
||||||
|
),
|
||||||
|
) -> Expression {
|
||||||
|
let start = self.pos;
|
||||||
|
|
||||||
|
let name = (&input.0)(self);
|
||||||
|
|
||||||
|
let mut args = vec![];
|
||||||
|
|
||||||
|
for item in input.1 {
|
||||||
|
self.consume(" ");
|
||||||
|
args.push(item(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
let end = self.pos;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_call((name, args), start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_call(input: impl Into<ast::Call>, start: usize, end: usize) -> Expression {
|
||||||
|
let call = input.into();
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr: RawExpression::Call(Box::new(call)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn var(&mut self, input: impl Into<String>) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
let (start, _) = self.consume("$");
|
||||||
|
let (_, end) = self.consume(&input);
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_var(input, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_var(input: impl Into<String>, start: usize, end: usize) -> Expression {
|
||||||
|
let input = input.into();
|
||||||
|
|
||||||
|
let expr = match &input[..] {
|
||||||
|
"it" => RawExpression::VariableReference(ast::Variable::It),
|
||||||
|
_ => RawExpression::VariableReference(ast::Variable::Other(input)),
|
||||||
|
};
|
||||||
|
|
||||||
|
Expression {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
expr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pipeline(
|
||||||
|
&mut self,
|
||||||
|
input: Vec<&dyn Fn(&mut ExpressionBuilder) -> Expression>,
|
||||||
|
) -> ast::Pipeline {
|
||||||
|
let start = self.pos;
|
||||||
|
|
||||||
|
let mut exprs = vec![];
|
||||||
|
let mut input = input.into_iter();
|
||||||
|
|
||||||
|
let next = input.next().unwrap();
|
||||||
|
exprs.push(next(self));
|
||||||
|
|
||||||
|
for item in input {
|
||||||
|
self.consume(" | ");
|
||||||
|
exprs.push(item(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
let end = self.pos;
|
||||||
|
|
||||||
|
ExpressionBuilder::spanned_pipeline(exprs, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_pipeline(input: Vec<Expression>, start: usize, end: usize) -> ast::Pipeline {
|
||||||
|
ast::Pipeline {
|
||||||
|
span: Span::from((start, end)),
|
||||||
|
commands: input,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sp(&mut self) {
|
||||||
|
self.consume(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ws(&mut self, input: &str) {
|
||||||
|
self.consume(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consume(&mut self, input: &str) -> (usize, usize) {
|
||||||
|
let start = self.pos;
|
||||||
|
self.pos += input.len();
|
||||||
|
(start, self.pos)
|
||||||
|
}
|
||||||
|
}
|
119
src/parser/ast/module.rs
Normal file
119
src/parser/ast/module.rs
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
use crate::parser::ast;
|
||||||
|
use crate::parser::lexer::{Span, Spanned};
|
||||||
|
use derive_new::new;
|
||||||
|
|
||||||
|
#[derive(new, Eq, PartialEq, Clone, Debug)]
|
||||||
|
pub struct Module {
|
||||||
|
span: Span,
|
||||||
|
items: Vec<Item>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Module {
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
let mut iter = self.items.iter();
|
||||||
|
|
||||||
|
let first = iter.next().unwrap();
|
||||||
|
let mut out = first.print();
|
||||||
|
|
||||||
|
for item in iter {
|
||||||
|
out.push_str(&format!("\n{}", item.print()));
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||||
|
pub enum RawItem {
|
||||||
|
Expression(ast::Pipeline),
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
Function(Function),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawItem {
|
||||||
|
fn print(&self) -> String {
|
||||||
|
match self {
|
||||||
|
RawItem::Expression(p) => p.print(),
|
||||||
|
RawItem::Function(f) => f.print(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Item = Spanned<RawItem>;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||||
|
pub enum Type {
|
||||||
|
Any,
|
||||||
|
Int,
|
||||||
|
Decimal,
|
||||||
|
Bytes,
|
||||||
|
Text,
|
||||||
|
Boolean,
|
||||||
|
Date,
|
||||||
|
Object,
|
||||||
|
List,
|
||||||
|
Block,
|
||||||
|
// Object(IndexMap<Spanned<String>, Spanned<Type>>),
|
||||||
|
// List(Box<Spanned<Type>>),
|
||||||
|
// Block {
|
||||||
|
// arguments: Spanned<Vec<Spanned<Type>>>,
|
||||||
|
// return_type: Box<Spanned<Type>>,
|
||||||
|
// },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type {
|
||||||
|
#[allow(unused)]
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
use Type::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Any => "any",
|
||||||
|
Int => "int",
|
||||||
|
Decimal => "decimal",
|
||||||
|
Bytes => "bytes",
|
||||||
|
Text => "text",
|
||||||
|
Boolean => "boolean",
|
||||||
|
Date => "date",
|
||||||
|
Object => "object",
|
||||||
|
List => "list",
|
||||||
|
Block => "block",
|
||||||
|
}
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Debug, new)]
|
||||||
|
pub struct FormalParameter {
|
||||||
|
name: ast::ParameterIdentifier,
|
||||||
|
ty: Spanned<Type>,
|
||||||
|
span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Debug, new)]
|
||||||
|
pub struct Function {
|
||||||
|
name: Spanned<ast::Bare>,
|
||||||
|
params: Vec<FormalParameter>,
|
||||||
|
return_type: Option<Box<Spanned<Type>>>,
|
||||||
|
body: Spanned<ast::Block>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Function {
|
||||||
|
crate fn print(&self) -> String {
|
||||||
|
use pretty::{BoxDoc, Doc};
|
||||||
|
|
||||||
|
let doc: Doc<BoxDoc<()>> = Doc::text("function")
|
||||||
|
.append(Doc::space())
|
||||||
|
.append(Doc::text(self.name.item.to_string()))
|
||||||
|
// todo: signature
|
||||||
|
.append(Doc::space())
|
||||||
|
.append(Doc::text("{"))
|
||||||
|
.append(Doc::newline())
|
||||||
|
.append(Doc::text(self.body.print()).nest(1))
|
||||||
|
.append(Doc::newline())
|
||||||
|
.append(Doc::text("}"));
|
||||||
|
|
||||||
|
format!("{}", doc.pretty(80))
|
||||||
|
}
|
||||||
|
}
|
77
src/parser/ast/module_builder.rs
Normal file
77
src/parser/ast/module_builder.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use crate::parser::ast::module::{Item, Module};
|
||||||
|
use crate::parser::ast::{self, module};
|
||||||
|
use crate::parser::lexer::{Span, Spanned};
|
||||||
|
use derive_new::new;
|
||||||
|
|
||||||
|
#[derive(new)]
|
||||||
|
pub struct ModuleBuilder {
|
||||||
|
#[new(default)]
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
impl ModuleBuilder {
|
||||||
|
// crate fn function(&mut self, input: ) -> Function {}
|
||||||
|
|
||||||
|
crate fn spanned_function(
|
||||||
|
input: (
|
||||||
|
Spanned<ast::Bare>,
|
||||||
|
Vec<module::FormalParameter>,
|
||||||
|
Option<Spanned<module::Type>>,
|
||||||
|
Spanned<ast::Block>,
|
||||||
|
),
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> module::Function {
|
||||||
|
module::Function::new(input.0, input.1, input.2.map(Box::new), input.3)
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn spanned_formal_parameter(
|
||||||
|
input: (ast::ParameterIdentifier, Spanned<module::Type>),
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> module::FormalParameter {
|
||||||
|
module::FormalParameter::new(input.0, input.1, Span::from((start, end)))
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn items(&mut self, input: Vec<&dyn Fn(&mut ModuleBuilder) -> Item>) -> Module {
|
||||||
|
let start = self.pos;
|
||||||
|
|
||||||
|
let mut items = vec![];
|
||||||
|
let mut input = input.into_iter();
|
||||||
|
|
||||||
|
let next = input.next().unwrap();
|
||||||
|
items.push(next(self));
|
||||||
|
|
||||||
|
for item in input {
|
||||||
|
self.consume(" | ");
|
||||||
|
items.push(item(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
let end = self.pos;
|
||||||
|
|
||||||
|
ModuleBuilder::spanned_items(items, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spanned_items(input: Vec<Item>, start: usize, end: usize) -> ast::Module {
|
||||||
|
ast::Module::new(Span::from((start, end)), input)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sp(&mut self) {
|
||||||
|
self.consume(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ws(&mut self, input: &str) {
|
||||||
|
self.consume(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn newline(&mut self) {
|
||||||
|
self.consume("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consume(&mut self, input: &str) -> (usize, usize) {
|
||||||
|
let start = self.pos;
|
||||||
|
self.pos += input.len();
|
||||||
|
(start, self.pos)
|
||||||
|
}
|
||||||
|
}
|
5
src/parser/ast/parser_utils.rs
Normal file
5
src/parser/ast/parser_utils.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
crate fn concat<T>(item: T, rest: Vec<T>) -> Vec<T> {
|
||||||
|
let mut out = vec![item];
|
||||||
|
out.extend(rest);
|
||||||
|
out
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ use crate::errors::ShellError;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use logos_derive::Logos;
|
use logos_derive::Logos;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Logos)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Logos)]
|
||||||
|
@ -13,6 +14,10 @@ crate enum TopToken {
|
||||||
#[end]
|
#[end]
|
||||||
END,
|
END,
|
||||||
|
|
||||||
|
#[token = "function"]
|
||||||
|
#[callback = "after_function"]
|
||||||
|
Function,
|
||||||
|
|
||||||
#[regex = "-?[0-9]+"]
|
#[regex = "-?[0-9]+"]
|
||||||
#[callback = "after_num"]
|
#[callback = "after_num"]
|
||||||
Num,
|
Num,
|
||||||
|
@ -27,7 +32,7 @@ crate enum TopToken {
|
||||||
#[callback = "start_variable"]
|
#[callback = "start_variable"]
|
||||||
Dollar,
|
Dollar,
|
||||||
|
|
||||||
#[regex = r#"[^\s0-9"'$\-][^\s"']*"#]
|
#[regex = r#"[^\s0-9"'$\-(){}][^\s"'(){}]*"#]
|
||||||
#[callback = "end_bare_variable"]
|
#[callback = "end_bare_variable"]
|
||||||
Bare,
|
Bare,
|
||||||
|
|
||||||
|
@ -73,16 +78,21 @@ crate enum TopToken {
|
||||||
#[token = "-"]
|
#[token = "-"]
|
||||||
Dash,
|
Dash,
|
||||||
|
|
||||||
#[regex = r"\s+"]
|
#[regex = r"[^\S\r\n]"]
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
|
||||||
|
#[regex = r"(\r\n|\n)"]
|
||||||
|
Newline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopToken {
|
impl TopToken {
|
||||||
fn to_token(&self) -> Option<Token> {
|
fn to_token(&self, _text: &str) -> Option<Token> {
|
||||||
use TopToken::*;
|
use TopToken::*;
|
||||||
|
|
||||||
let result = match self {
|
let result = match self {
|
||||||
END => return None,
|
END => return None,
|
||||||
|
Function => Token::KeywordFunction,
|
||||||
|
Newline => Token::Newline,
|
||||||
Num => Token::Num,
|
Num => Token::Num,
|
||||||
SQString => Token::SQString,
|
SQString => Token::SQString,
|
||||||
DQString => Token::DQString,
|
DQString => Token::DQString,
|
||||||
|
@ -112,17 +122,187 @@ impl TopToken {
|
||||||
|
|
||||||
fn after_num<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
fn after_num<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
||||||
trace!("after_num EXTRAS={:?}", lex.extras);
|
trace!("after_num EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::AfterNum;
|
lex.extras.push(LexerStateName::AfterNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn after_function<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
||||||
|
trace!("after_function EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.push(LexerStateName::AfterFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_variable<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
fn start_variable<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
||||||
trace!("start_variable EXTRAS={:?}", lex.extras);
|
trace!("start_variable EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::Var;
|
lex.extras.push(LexerStateName::VariableToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_bare_variable<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
fn end_bare_variable<S>(lex: &mut logos::Lexer<TopToken, S>) {
|
||||||
trace!("end_variable EXTRAS={:?}", lex.extras);
|
trace!("end_bare_variable EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::AfterVariableToken;
|
lex.extras.push(LexerStateName::AfterVariableToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
#[extras = "LexerState"]
|
||||||
|
crate enum AfterFunction {
|
||||||
|
#[error]
|
||||||
|
Error,
|
||||||
|
|
||||||
|
#[end]
|
||||||
|
END,
|
||||||
|
|
||||||
|
#[regex = r"[A-Za-z][A-Za-z0-9_\-]*"]
|
||||||
|
#[callback = "after_function_name"]
|
||||||
|
CommandName,
|
||||||
|
|
||||||
|
#[token = "{"]
|
||||||
|
#[callback = "start_function_block"]
|
||||||
|
OpenBrace,
|
||||||
|
|
||||||
|
#[regex = r"[^\S\r\n]"]
|
||||||
|
Whitespace,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AfterFunction {
|
||||||
|
fn to_token(&self) -> Option<Token> {
|
||||||
|
use AfterFunction::*;
|
||||||
|
|
||||||
|
let result = match self {
|
||||||
|
END => return None,
|
||||||
|
CommandName => Token::CommandName,
|
||||||
|
Whitespace => Token::Whitespace,
|
||||||
|
OpenBrace => Token::OpenBrace,
|
||||||
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn after_function_name<S>(lex: &mut logos::Lexer<AfterFunction, S>) {
|
||||||
|
trace!("after_function_name EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.push(LexerStateName::AfterFunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_function_block<S>(lex: &mut logos::Lexer<AfterFunction, S>) {
|
||||||
|
trace!("start_function_block EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
#[extras = "LexerState"]
|
||||||
|
crate enum AfterFunctionName {
|
||||||
|
#[error]
|
||||||
|
Error,
|
||||||
|
|
||||||
|
#[end]
|
||||||
|
END,
|
||||||
|
|
||||||
|
#[token = "("]
|
||||||
|
#[callback = "start_param_list"]
|
||||||
|
StartParamList,
|
||||||
|
|
||||||
|
#[regex = r"[^\S\r\n]"]
|
||||||
|
Whitespace,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AfterFunctionName {
|
||||||
|
fn to_token(&self) -> Option<Token> {
|
||||||
|
use AfterFunctionName::*;
|
||||||
|
|
||||||
|
let result = match self {
|
||||||
|
END => return None,
|
||||||
|
StartParamList => Token::StartParamList,
|
||||||
|
Whitespace => Token::Whitespace,
|
||||||
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_param_list<S>(lex: &mut logos::Lexer<AfterFunctionName, S>) {
|
||||||
|
trace!("start_param_list EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.push(LexerStateName::InParamList);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
#[extras = "LexerState"]
|
||||||
|
crate enum InParamList {
|
||||||
|
#[error]
|
||||||
|
Error,
|
||||||
|
|
||||||
|
#[end]
|
||||||
|
END,
|
||||||
|
|
||||||
|
#[token = "$"]
|
||||||
|
#[callback = "start_param_name"]
|
||||||
|
Dollar,
|
||||||
|
|
||||||
|
#[regex = r"[^\S\r\n]"]
|
||||||
|
Whitespace,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InParamList {
|
||||||
|
fn to_token(&self) -> Option<Token> {
|
||||||
|
use InParamList::*;
|
||||||
|
|
||||||
|
let result = match self {
|
||||||
|
END => return None,
|
||||||
|
Dollar => Token::Dollar,
|
||||||
|
Whitespace => Token::Whitespace,
|
||||||
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_param_name<S>(lex: &mut logos::Lexer<InParamList, S>) {
|
||||||
|
trace!("start_param_name EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.push(LexerStateName::VariableToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
#[extras = "LexerState"]
|
||||||
|
crate enum TypeTokens {
|
||||||
|
#[error]
|
||||||
|
Error,
|
||||||
|
|
||||||
|
#[end]
|
||||||
|
END,
|
||||||
|
|
||||||
|
#[regex = "(any|int|decimal|bytes|text|boolean|date|object|list|block)"]
|
||||||
|
#[callback = "end_type_token"]
|
||||||
|
TypeName,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_type_token<S>(lex: &mut logos::Lexer<TypeTokens, S>) {
|
||||||
|
trace!("end_type_token EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeTokens {
|
||||||
|
fn to_token(&self, text: &str) -> Option<Token> {
|
||||||
|
use TypeTokens::*;
|
||||||
|
|
||||||
|
let result = match self {
|
||||||
|
END => return None,
|
||||||
|
TypeName => match text {
|
||||||
|
"any" => Token::TyAny,
|
||||||
|
"int" => Token::TyInt,
|
||||||
|
"decimal" => Token::TyDecimal,
|
||||||
|
"bytes" => Token::TyBytes,
|
||||||
|
"text" => Token::TyText,
|
||||||
|
"boolean" => Token::TyBoolean,
|
||||||
|
"date" => Token::TyDate,
|
||||||
|
"object" => Token::TyObject,
|
||||||
|
"list" => Token::TyList,
|
||||||
|
other => unreachable!("Type name {:?} shouldn't be possible", other),
|
||||||
|
},
|
||||||
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
@ -138,9 +318,12 @@ crate enum AfterNum {
|
||||||
#[callback = "end_unit"]
|
#[callback = "end_unit"]
|
||||||
Unit,
|
Unit,
|
||||||
|
|
||||||
#[regex = r"\s"]
|
#[regex = r"[^\S\r\n]"]
|
||||||
#[callback = "end_number"]
|
#[callback = "end_number"]
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
|
||||||
|
#[regex = r"(\r\n|\n)"]
|
||||||
|
Newline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AfterNum {
|
impl AfterNum {
|
||||||
|
@ -151,6 +334,7 @@ impl AfterNum {
|
||||||
END => return None,
|
END => return None,
|
||||||
Unit => Token::Unit,
|
Unit => Token::Unit,
|
||||||
Whitespace => Token::Whitespace,
|
Whitespace => Token::Whitespace,
|
||||||
|
Newline => Token::Newline,
|
||||||
Error => unreachable!("Don't call to_token with the error variant"),
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -160,12 +344,12 @@ impl AfterNum {
|
||||||
|
|
||||||
fn end_unit<S>(lex: &mut logos::Lexer<AfterNum, S>) {
|
fn end_unit<S>(lex: &mut logos::Lexer<AfterNum, S>) {
|
||||||
trace!("end_unit EXTRAS={:?}", lex.extras);
|
trace!("end_unit EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::Top;
|
lex.extras.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_number<S>(lex: &mut logos::Lexer<AfterNum, S>) {
|
fn end_number<S>(lex: &mut logos::Lexer<AfterNum, S>) {
|
||||||
trace!("end_unit EXTRAS={:?}", lex.extras);
|
trace!("end_number EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::Top;
|
lex.extras.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
@ -183,7 +367,7 @@ crate enum VariableToken {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VariableToken {
|
impl VariableToken {
|
||||||
fn to_token(&self) -> Option<Token> {
|
fn to_token(&self, _text: &str) -> Option<Token> {
|
||||||
use VariableToken::*;
|
use VariableToken::*;
|
||||||
|
|
||||||
let result = match self {
|
let result = match self {
|
||||||
|
@ -198,7 +382,7 @@ impl VariableToken {
|
||||||
|
|
||||||
fn end_variable<S>(lex: &mut logos::Lexer<VariableToken, S>) {
|
fn end_variable<S>(lex: &mut logos::Lexer<VariableToken, S>) {
|
||||||
trace!("end_variable EXTRAS={:?}", lex.extras);
|
trace!("end_variable EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::AfterVariableToken;
|
lex.extras.replace(LexerStateName::AfterVariableToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
@ -214,9 +398,20 @@ crate enum AfterVariableToken {
|
||||||
#[callback = "start_member"]
|
#[callback = "start_member"]
|
||||||
Dot,
|
Dot,
|
||||||
|
|
||||||
#[regex = r"\s"]
|
#[token = ":"]
|
||||||
|
#[callback = "start_type"]
|
||||||
|
Colon,
|
||||||
|
|
||||||
|
#[regex = r"[^\S\r\n]"]
|
||||||
#[callback = "terminate_variable"]
|
#[callback = "terminate_variable"]
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
|
||||||
|
#[token = ")"]
|
||||||
|
#[callback = "end_param_list"]
|
||||||
|
EndParamList,
|
||||||
|
|
||||||
|
#[regex = r"(\r\n|\n)"]
|
||||||
|
Newline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AfterVariableToken {
|
impl AfterVariableToken {
|
||||||
|
@ -226,7 +421,10 @@ impl AfterVariableToken {
|
||||||
let result = match self {
|
let result = match self {
|
||||||
END => return None,
|
END => return None,
|
||||||
Dot => Token::PathDot,
|
Dot => Token::PathDot,
|
||||||
|
Colon => Token::Colon,
|
||||||
Whitespace => Token::Whitespace,
|
Whitespace => Token::Whitespace,
|
||||||
|
Newline => Token::Newline,
|
||||||
|
EndParamList => Token::EndParamList,
|
||||||
Error => unreachable!("Don't call to_token with the error variant"),
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -235,13 +433,26 @@ impl AfterVariableToken {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_member<S>(lex: &mut logos::Lexer<AfterVariableToken, S>) {
|
fn start_member<S>(lex: &mut logos::Lexer<AfterVariableToken, S>) {
|
||||||
trace!("start_variable EXTRAS={:?}", lex.extras);
|
trace!("start_member EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::AfterMemberDot;
|
lex.extras.push(LexerStateName::AfterMemberDot);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_param_list<S>(lex: &mut logos::Lexer<AfterVariableToken, S>) {
|
||||||
|
trace!("end_param_list EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.pop();
|
||||||
|
lex.extras.pop();
|
||||||
|
lex.extras.pop();
|
||||||
|
lex.extras.push(LexerStateName::AfterParamList);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_type<S>(lex: &mut logos::Lexer<AfterVariableToken, S>) {
|
||||||
|
trace!("start_type EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.push(LexerStateName::TypeTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn terminate_variable<S>(lex: &mut logos::Lexer<AfterVariableToken, S>) {
|
fn terminate_variable<S>(lex: &mut logos::Lexer<AfterVariableToken, S>) {
|
||||||
trace!("terminate_variable EXTRAS={:?}", lex.extras);
|
trace!("terminate_variable EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::Top;
|
lex.extras.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
@ -263,8 +474,11 @@ crate enum AfterMemberDot {
|
||||||
#[regex = r#""([^"]|\\")*""#]
|
#[regex = r#""([^"]|\\")*""#]
|
||||||
DQString,
|
DQString,
|
||||||
|
|
||||||
#[regex = r"\s"]
|
#[regex = r"[^\S\r\n]"]
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
|
||||||
|
#[regex = r"(\r\n|\n)"]
|
||||||
|
Newline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AfterMemberDot {
|
impl AfterMemberDot {
|
||||||
|
@ -278,6 +492,7 @@ impl AfterMemberDot {
|
||||||
DQString => Token::DQMember,
|
DQString => Token::DQMember,
|
||||||
|
|
||||||
Whitespace => Token::Whitespace,
|
Whitespace => Token::Whitespace,
|
||||||
|
Newline => Token::Newline,
|
||||||
Error => unreachable!("Don't call to_token with the error variant"),
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -287,13 +502,51 @@ impl AfterMemberDot {
|
||||||
|
|
||||||
fn finish_member<S>(lex: &mut logos::Lexer<AfterMemberDot, S>) {
|
fn finish_member<S>(lex: &mut logos::Lexer<AfterMemberDot, S>) {
|
||||||
trace!("finish_member EXTRAS={:?}", lex.extras);
|
trace!("finish_member EXTRAS={:?}", lex.extras);
|
||||||
lex.extras.current = LexerStateName::AfterVariableToken;
|
lex.extras.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Logos, Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
#[extras = "LexerState"]
|
||||||
|
crate enum AfterParamList {
|
||||||
|
#[error]
|
||||||
|
Error,
|
||||||
|
|
||||||
|
#[token = "->"]
|
||||||
|
#[callback = "finish_arrow"]
|
||||||
|
Arrow,
|
||||||
|
|
||||||
|
#[end]
|
||||||
|
END,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AfterParamList {
|
||||||
|
fn to_token(&self, _text: &str) -> Option<Token> {
|
||||||
|
use AfterParamList::*;
|
||||||
|
|
||||||
|
let result = match self {
|
||||||
|
END => return None,
|
||||||
|
Arrow => Token::ReturnArrow,
|
||||||
|
Error => unreachable!("Don't call to_token with the error variant"),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_arrow<S>(lex: &mut logos::Lexer<AfterParamList, S>) {
|
||||||
|
trace!("finish_arrow EXTRAS={:?}", lex.extras);
|
||||||
|
lex.extras.replace(LexerStateName::TypeTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
crate enum LexerStateName {
|
crate enum LexerStateName {
|
||||||
Top,
|
Top,
|
||||||
Var,
|
VariableToken,
|
||||||
|
AfterFunction,
|
||||||
|
AfterFunctionName,
|
||||||
|
TypeTokens,
|
||||||
|
InParamList,
|
||||||
|
AfterParamList,
|
||||||
AfterMemberDot,
|
AfterMemberDot,
|
||||||
AfterNum,
|
AfterNum,
|
||||||
AfterVariableToken,
|
AfterVariableToken,
|
||||||
|
@ -305,9 +558,48 @@ impl Default for LexerStateName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
crate struct LexerState {
|
crate struct LexerState {
|
||||||
current: LexerStateName,
|
stack: VecDeque<LexerStateName>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LexerState {
|
||||||
|
fn default() -> LexerState {
|
||||||
|
let mut stack = VecDeque::new();
|
||||||
|
stack.push_back(LexerStateName::Top);
|
||||||
|
LexerState { stack }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LexerState {
|
||||||
|
crate fn debug_states(&self) -> String {
|
||||||
|
let items: Vec<String> = self.stack.iter().map(|s| format!("{:?}", s)).collect();
|
||||||
|
let debug = itertools::join(items, " -> ");
|
||||||
|
format!("{}", debug)
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn push(&mut self, name: LexerStateName) {
|
||||||
|
self.stack.push_back(name);
|
||||||
|
trace!("push {:?} (to {})", name, self.debug_states());
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn replace(&mut self, name: LexerStateName) {
|
||||||
|
self.stack.pop_back();
|
||||||
|
self.stack.push_back(name);
|
||||||
|
trace!("replace with {:?} (to {})", name, self.debug_states());
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn pop(&mut self) {
|
||||||
|
self.stack.pop_back();
|
||||||
|
trace!("pop (to {})", self.debug_states());
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn current(&self) -> LexerStateName {
|
||||||
|
*self
|
||||||
|
.stack
|
||||||
|
.back()
|
||||||
|
.expect("There must always be at least one state in the lexer stack")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl logos::Extras for LexerState {
|
impl logos::Extras for LexerState {
|
||||||
|
@ -315,7 +607,7 @@ impl logos::Extras for LexerState {
|
||||||
fn on_whitespace(&mut self, _byte: u8) {}
|
fn on_whitespace(&mut self, _byte: u8) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||||
pub struct Span {
|
pub struct Span {
|
||||||
crate start: usize,
|
crate start: usize,
|
||||||
crate end: usize,
|
crate end: usize,
|
||||||
|
@ -374,7 +666,7 @@ impl language_reporting::ReportingSpan for Span {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(new, Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(new, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
pub struct Spanned<T> {
|
pub struct Spanned<T> {
|
||||||
crate span: Span,
|
crate span: Span,
|
||||||
crate item: T,
|
crate item: T,
|
||||||
|
@ -389,8 +681,18 @@ impl<T> std::ops::Deref for Spanned<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Spanned<T> {
|
impl<T> Spanned<T> {
|
||||||
crate fn from_item(item: T, span: Span) -> Spanned<T> {
|
crate fn from_item(item: T, span: impl Into<Span>) -> Spanned<T> {
|
||||||
Spanned { span, item }
|
Spanned {
|
||||||
|
span: span.into(),
|
||||||
|
item,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn map<U>(self, input: impl FnOnce(T) -> U) -> Spanned<U> {
|
||||||
|
let Spanned { span, item } = self;
|
||||||
|
|
||||||
|
let mapped = input(item);
|
||||||
|
Spanned { span, item: mapped }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,10 +708,6 @@ impl SpannedToken<'source> {
|
||||||
Spanned::from_item(self.slice.to_string(), self.span)
|
Spanned::from_item(self.slice.to_string(), self.span)
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn to_string(&self) -> String {
|
|
||||||
self.slice.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn as_slice(&self) -> &str {
|
crate fn as_slice(&self) -> &str {
|
||||||
self.slice
|
self.slice
|
||||||
}
|
}
|
||||||
|
@ -417,8 +715,14 @@ impl SpannedToken<'source> {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
|
KeywordFunction,
|
||||||
|
CommandName,
|
||||||
|
#[allow(unused)]
|
||||||
|
Comma,
|
||||||
|
Colon,
|
||||||
Variable,
|
Variable,
|
||||||
PathDot,
|
PathDot,
|
||||||
|
ReturnArrow,
|
||||||
Member,
|
Member,
|
||||||
SQMember,
|
SQMember,
|
||||||
DQMember,
|
DQMember,
|
||||||
|
@ -433,6 +737,8 @@ pub enum Token {
|
||||||
CloseBrace,
|
CloseBrace,
|
||||||
OpenParen,
|
OpenParen,
|
||||||
CloseParen,
|
CloseParen,
|
||||||
|
StartParamList,
|
||||||
|
EndParamList,
|
||||||
OpGt,
|
OpGt,
|
||||||
OpLt,
|
OpLt,
|
||||||
OpGte,
|
OpGte,
|
||||||
|
@ -441,23 +747,26 @@ pub enum Token {
|
||||||
OpNeq,
|
OpNeq,
|
||||||
Dash,
|
Dash,
|
||||||
DashDash,
|
DashDash,
|
||||||
|
TyAny,
|
||||||
|
#[allow(unused)]
|
||||||
|
TyBlock,
|
||||||
|
TyBoolean,
|
||||||
|
TyBytes,
|
||||||
|
TyDate,
|
||||||
|
TyDecimal,
|
||||||
|
TyInt,
|
||||||
|
TyList,
|
||||||
|
TyObject,
|
||||||
|
TyText,
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
Newline,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Debug, Clone, Eq, PartialEq)]
|
|
||||||
// crate enum Token<'source> {
|
|
||||||
// Top(SpannedToken<'source, TopToken>),
|
|
||||||
// Var(SpannedToken<'source, VariableToken>),
|
|
||||||
// Dot(SpannedToken<'source, &'source str>),
|
|
||||||
// Member(SpannedToken<'source, &'source str>),
|
|
||||||
// Whitespace(SpannedToken<'source, &'source str>),
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
crate struct Lexer<'source> {
|
crate struct Lexer<'source> {
|
||||||
lexer: logos::Lexer<TopToken, &'source str>,
|
lexer: logos::Lexer<TopToken, &'source str>,
|
||||||
first: bool,
|
first: bool,
|
||||||
whitespace: bool, // state: LexerState
|
whitespace: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lexer<'source> {
|
impl Lexer<'source> {
|
||||||
|
@ -465,41 +774,71 @@ impl Lexer<'source> {
|
||||||
Lexer {
|
Lexer {
|
||||||
first: true,
|
first: true,
|
||||||
lexer: logos::Logos::lexer(source),
|
lexer: logos::Logos::lexer(source),
|
||||||
whitespace
|
whitespace,
|
||||||
// state: LexerState::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lex_error(&self, range: &Range<usize>) -> ShellError {
|
||||||
|
use language_reporting::*;
|
||||||
|
|
||||||
|
let states = self.lexer.extras.debug_states();
|
||||||
|
|
||||||
|
ShellError::diagnostic(
|
||||||
|
Diagnostic::new(Severity::Error, "Lex error")
|
||||||
|
.with_label(Label::new_primary(Span::new(range)).with_message(states)),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for Lexer<'source> {
|
impl Iterator for Lexer<'source> {
|
||||||
type Item = Result<(usize, SpannedToken<'source>, usize), ShellError>;
|
type Item = Result<(usize, SpannedToken<'source>, usize), ShellError>;
|
||||||
// type Item = Result<Token<'source>, ShellError>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.first {
|
let result = if self.first {
|
||||||
self.first = false;
|
self.first = false;
|
||||||
|
|
||||||
match self.lexer.token {
|
match self.lexer.token {
|
||||||
TopToken::Error => {
|
TopToken::Error => Some(Err(self.lex_error(&self.lexer.range()))),
|
||||||
return Some(Err(lex_error(&self.lexer.range(), self.lexer.source)))
|
TopToken::Whitespace if !self.whitespace => self.next(),
|
||||||
}
|
other => spanned(
|
||||||
TopToken::Whitespace if !self.whitespace => return self.next(),
|
other.to_token(self.lexer.slice())?,
|
||||||
other => {
|
self.lexer.slice(),
|
||||||
return spanned(other.to_token()?, self.lexer.slice(), &self.lexer.range())
|
&self.lexer.range(),
|
||||||
}
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
trace!("STATE={:?}", self.lexer.extras);
|
trace!("STATE={:?}", self.lexer.extras);
|
||||||
|
|
||||||
match self.lexer.extras.current {
|
match self.lexer.extras.current() {
|
||||||
LexerStateName::Top => {
|
LexerStateName::Top => {
|
||||||
let (lexer, range, slice, token) = advance::<TopToken>(self.lexer.clone());
|
let (lexer, range, slice, token) = advance::<TopToken>(self.lexer.clone());
|
||||||
self.lexer = lexer;
|
self.lexer = lexer;
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
TopToken::Error => return Some(Err(lex_error(&range, self.lexer.source))),
|
TopToken::Error => Some(Err(self.lex_error(&range))),
|
||||||
TopToken::Whitespace if !self.whitespace => return self.next(),
|
TopToken::Whitespace if !self.whitespace => self.next(),
|
||||||
other => return spanned(other.to_token()?, slice, &range),
|
other => spanned(other.to_token(slice)?, slice, &range),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LexerStateName::AfterParamList => {
|
||||||
|
let (lexer, range, slice, token) =
|
||||||
|
advance::<AfterParamList>(self.lexer.clone());
|
||||||
|
self.lexer = lexer;
|
||||||
|
|
||||||
|
match token {
|
||||||
|
AfterParamList::Error => Some(Err(self.lex_error(&range))),
|
||||||
|
other => spanned(other.to_token(slice)?, slice, &range),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LexerStateName::TypeTokens => {
|
||||||
|
let (lexer, range, slice, token) = advance::<TypeTokens>(self.lexer.clone());
|
||||||
|
self.lexer = lexer;
|
||||||
|
|
||||||
|
match token {
|
||||||
|
TypeTokens::Error => Some(Err(self.lex_error(&range))),
|
||||||
|
other => spanned(other.to_token(slice)?, slice, &range),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,8 +847,42 @@ impl Iterator for Lexer<'source> {
|
||||||
self.lexer = lexer;
|
self.lexer = lexer;
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
AfterNum::Error => return Some(Err(lex_error(&range, self.lexer.source))),
|
AfterNum::Error => Some(Err(self.lex_error(&range))),
|
||||||
AfterNum::Whitespace if !self.whitespace => self.next(),
|
AfterNum::Whitespace if !self.whitespace => self.next(),
|
||||||
|
other => spanned(other.to_token()?, slice, &range),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LexerStateName::AfterFunction => {
|
||||||
|
let (lexer, range, slice, token) = advance::<AfterFunction>(self.lexer.clone());
|
||||||
|
self.lexer = lexer;
|
||||||
|
|
||||||
|
match token {
|
||||||
|
AfterFunction::Error => Some(Err(self.lex_error(&range))),
|
||||||
|
AfterFunction::Whitespace if !self.whitespace => self.next(),
|
||||||
|
other => spanned(other.to_token()?, slice, &range),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LexerStateName::AfterFunctionName => {
|
||||||
|
let (lexer, range, slice, token) =
|
||||||
|
advance::<AfterFunctionName>(self.lexer.clone());
|
||||||
|
self.lexer = lexer;
|
||||||
|
|
||||||
|
match token {
|
||||||
|
AfterFunctionName::Error => Some(Err(self.lex_error(&range))),
|
||||||
|
AfterFunctionName::Whitespace if !self.whitespace => self.next(),
|
||||||
|
other => spanned(other.to_token()?, slice, &range),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LexerStateName::InParamList => {
|
||||||
|
let (lexer, range, slice, token) = advance::<InParamList>(self.lexer.clone());
|
||||||
|
self.lexer = lexer;
|
||||||
|
|
||||||
|
match token {
|
||||||
|
InParamList::Error => Some(Err(self.lex_error(&range))),
|
||||||
|
InParamList::Whitespace if !self.whitespace => self.next(),
|
||||||
other => return spanned(other.to_token()?, slice, &range),
|
other => return spanned(other.to_token()?, slice, &range),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,11 +893,9 @@ impl Iterator for Lexer<'source> {
|
||||||
self.lexer = lexer;
|
self.lexer = lexer;
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
AfterMemberDot::Error => {
|
AfterMemberDot::Error => return Some(Err(self.lex_error(&range))),
|
||||||
return Some(Err(lex_error(&range, self.lexer.source)))
|
|
||||||
}
|
|
||||||
AfterMemberDot::Whitespace if !self.whitespace => self.next(),
|
AfterMemberDot::Whitespace if !self.whitespace => self.next(),
|
||||||
other => return spanned(other.to_token()?, slice, &range),
|
other => spanned(other.to_token()?, slice, &range),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,37 +905,28 @@ impl Iterator for Lexer<'source> {
|
||||||
self.lexer = lexer;
|
self.lexer = lexer;
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
AfterVariableToken::Error => {
|
AfterVariableToken::Error => Some(Err(self.lex_error(&range))),
|
||||||
return Some(Err(lex_error(&range, self.lexer.source)))
|
|
||||||
}
|
|
||||||
AfterVariableToken::Whitespace if !self.whitespace => self.next(),
|
AfterVariableToken::Whitespace if !self.whitespace => self.next(),
|
||||||
other => return spanned(other.to_token()?, slice, &range),
|
other => spanned(other.to_token()?, slice, &range),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LexerStateName::Var => {
|
LexerStateName::VariableToken => {
|
||||||
let (lexer, range, slice, token) = advance::<VariableToken>(self.lexer.clone());
|
let (lexer, range, slice, token) = advance::<VariableToken>(self.lexer.clone());
|
||||||
self.lexer = lexer;
|
self.lexer = lexer;
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
VariableToken::Error => {
|
VariableToken::Error => Some(Err(self.lex_error(&range))),
|
||||||
return Some(Err(lex_error(&range, self.lexer.source)))
|
other => spanned(other.to_token(slice)?, slice, &range),
|
||||||
}
|
|
||||||
other => return spanned(other.to_token()?, slice, &range),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lex_error(range: &Range<usize>, _source: &str) -> ShellError {
|
trace!("emitting {:?}", result);
|
||||||
use language_reporting::*;
|
|
||||||
|
|
||||||
ShellError::diagnostic(
|
result
|
||||||
Diagnostic::new(Severity::Error, "Lex error")
|
}
|
||||||
.with_label(Label::new_primary(Span::new(range))),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spanned<'source>(
|
fn spanned<'source>(
|
||||||
|
@ -600,6 +962,8 @@ mod tests {
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
fn assert_lex(source: &str, tokens: &[TestToken<'_>]) {
|
fn assert_lex(source: &str, tokens: &[TestToken<'_>]) {
|
||||||
|
let _ = pretty_env_logger::try_init();
|
||||||
|
|
||||||
let lex = Lexer::new(source, false);
|
let lex = Lexer::new(source, false);
|
||||||
let mut current = 0;
|
let mut current = 0;
|
||||||
|
|
||||||
|
@ -629,7 +993,26 @@ mod tests {
|
||||||
let actual_tokens: Result<Vec<SpannedToken>, _> =
|
let actual_tokens: Result<Vec<SpannedToken>, _> =
|
||||||
lex.map(|result| result.map(|(_, i, _)| i)).collect();
|
lex.map(|result| result.map(|(_, i, _)| i)).collect();
|
||||||
|
|
||||||
let actual_tokens = actual_tokens.unwrap();
|
let actual_tokens = match actual_tokens {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(ShellError::Diagnostic(diag)) => {
|
||||||
|
use language_reporting::termcolor;
|
||||||
|
|
||||||
|
let writer = termcolor::StandardStream::stdout(termcolor::ColorChoice::Auto);
|
||||||
|
let files = crate::parser::span::Files::new(source.to_string());
|
||||||
|
|
||||||
|
language_reporting::emit(
|
||||||
|
&mut writer.lock(),
|
||||||
|
&files,
|
||||||
|
&diag.diagnostic,
|
||||||
|
&language_reporting::DefaultConfig,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
panic!("Test failed")
|
||||||
|
}
|
||||||
|
Err(err) => panic!("Something went wrong during lex: {:#?}", err),
|
||||||
|
};
|
||||||
|
|
||||||
assert_eq!(actual_tokens, expected_tokens);
|
assert_eq!(actual_tokens, expected_tokens);
|
||||||
}
|
}
|
||||||
|
@ -652,12 +1035,16 @@ mod tests {
|
||||||
impl TestToken<'source> {
|
impl TestToken<'source> {
|
||||||
fn to_token(&self, range: &std::ops::Range<usize>) -> SpannedToken<'source> {
|
fn to_token(&self, range: &std::ops::Range<usize>) -> SpannedToken<'source> {
|
||||||
match self.desc {
|
match self.desc {
|
||||||
TokenDesc::Top(tok) => {
|
TokenDesc::Top(tok) => SpannedToken::new(
|
||||||
SpannedToken::new(Span::new(range), self.source, tok.to_token().unwrap())
|
Span::new(range),
|
||||||
}
|
self.source,
|
||||||
TokenDesc::Var(tok) => {
|
tok.to_token(&self.source).unwrap(),
|
||||||
SpannedToken::new(Span::new(range), self.source, tok.to_token().unwrap())
|
),
|
||||||
}
|
TokenDesc::Var(tok) => SpannedToken::new(
|
||||||
|
Span::new(range),
|
||||||
|
self.source,
|
||||||
|
tok.to_token(&self.source).unwrap(),
|
||||||
|
),
|
||||||
TokenDesc::Member => {
|
TokenDesc::Member => {
|
||||||
SpannedToken::new(Span::new(range), self.source, Token::Member)
|
SpannedToken::new(Span::new(range), self.source, Token::Member)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use crate::parser::ast::*;
|
use crate::parser::ast::expression::*;
|
||||||
|
use crate::parser::ast::module::*;
|
||||||
|
use crate::parser::ast::parser_utils::*;
|
||||||
|
use crate::parser::ast::{ExpressionBuilder, ModuleBuilder};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::parser::lexer::{SpannedToken, Spanned, Span, Token};
|
use crate::parser::lexer::{SpannedToken, Spanned, Span, Token};
|
||||||
use byte_unit::Byte;
|
use byte_unit::Byte;
|
||||||
|
@ -26,7 +30,73 @@ use byte_unit::Byte;
|
||||||
|
|
||||||
grammar<'input>;
|
grammar<'input>;
|
||||||
|
|
||||||
pub Pipeline: Pipeline = {
|
// === MODULES === //
|
||||||
|
|
||||||
|
pub Module: Module = {
|
||||||
|
<l: @L> <first:Item> <items: ( ("newline")+ <Item> )*> <r: @R> => ModuleBuilder::spanned_items(concat(first, items), l, r),
|
||||||
|
}
|
||||||
|
|
||||||
|
Item: Item = {
|
||||||
|
<l: @L> <pipeline:Pipeline> <r: @R> => Spanned::from_item(RawItem::Expression(pipeline), Span::from((l, r))),
|
||||||
|
<l: @L> <function:Function> <r: @R> => Spanned::from_item(RawItem::Function(function), Span::from((l, r))),
|
||||||
|
}
|
||||||
|
|
||||||
|
// === FUNCTIONS === //
|
||||||
|
|
||||||
|
Function: Function = {
|
||||||
|
<l: @L> "function" <bare: CommandName> "start-params"
|
||||||
|
<params: ParameterList>
|
||||||
|
"end-params" <ret: ("->" <Type>)?> <block: Block> <r: @R> => {
|
||||||
|
ModuleBuilder::spanned_function((bare, params, ret, block), l, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterList: Vec<FormalParameter> = {
|
||||||
|
<params: Comma<FormalParameter>> => params
|
||||||
|
}
|
||||||
|
|
||||||
|
FormalParameter: FormalParameter = {
|
||||||
|
<l: @L> <name: ParameterName> ":" <ty: Type> <r: @R> => ModuleBuilder::spanned_formal_parameter((name, ty), l, r),
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterName: ParameterIdentifier = {
|
||||||
|
<l: @L> "-" <b: SpannedBare> <r: @R> => ParameterIdentifier::shorthand(b.map(|b| b.to_string()), (l, r)),
|
||||||
|
<l: @L> "--" <b: SpannedBare> <r: @R> => ParameterIdentifier::flag(b.map(|b| b.to_string()), (l, r)),
|
||||||
|
<l: @L> <var: ParameterVariable> <r: @R> => ParameterIdentifier::var(var, (l, r)),
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterVariable: Spanned<Variable> = {
|
||||||
|
<l: @L> "$" <v: "variable"> <r: @R> => Spanned::from_item(ast::Variable::from_string(v.as_slice()), (l, r)),
|
||||||
|
}
|
||||||
|
|
||||||
|
// === TYPES === //
|
||||||
|
|
||||||
|
Type: Spanned<Type> = {
|
||||||
|
<l: @L> <ty: RawType> <r: @R> => Spanned::from_item(ty, (l, r)),
|
||||||
|
}
|
||||||
|
|
||||||
|
RawType: Type = {
|
||||||
|
"any" => Type::Any,
|
||||||
|
"int" => Type::Int,
|
||||||
|
"decimal" => Type::Decimal,
|
||||||
|
"bytes" => Type::Bytes,
|
||||||
|
"text" => Type::Text,
|
||||||
|
"boolean" => Type::Boolean,
|
||||||
|
"date" => Type::Date,
|
||||||
|
|
||||||
|
// TODO: generics
|
||||||
|
"object" => Type::Object,
|
||||||
|
"list" => Type::List,
|
||||||
|
"block" => Type::Block,
|
||||||
|
}
|
||||||
|
|
||||||
|
// === EXPRESSIONS === //
|
||||||
|
|
||||||
|
pub ReplLine: Pipeline = {
|
||||||
|
<Pipeline> ("newline")*
|
||||||
|
}
|
||||||
|
|
||||||
|
Pipeline: Pipeline = {
|
||||||
<l: @L> <first:PipelineElement> <rest: ( "|" <PipelineElement> )*> <r: @R> => Pipeline::from_parts(first, rest, l, r),
|
<l: @L> <first:PipelineElement> <rest: ( "|" <PipelineElement> )*> <r: @R> => Pipeline::from_parts(first, rest, l, r),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +127,18 @@ Binary: Expression = {
|
||||||
// In a block, a single bare word is interpreted as a call:
|
// In a block, a single bare word is interpreted as a call:
|
||||||
//
|
//
|
||||||
// foreach { ls }
|
// foreach { ls }
|
||||||
Block: Expression = {
|
Block: Spanned<Block> = {
|
||||||
|
<l: @L> "{" <expr: SingleExpression> "}" <r: @R> => ExpressionBuilder::spanned_raw_block(expr, l, r),
|
||||||
|
<l: @L> "{" <bare: BareExpression> "}" <r: @R> => {
|
||||||
|
let call = ExpressionBuilder::spanned_call(bare.clone(), bare.span.start, bare.span.end);
|
||||||
|
ExpressionBuilder::spanned_raw_block(call, l, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a block, a single bare word is interpreted as a call:
|
||||||
|
//
|
||||||
|
// foreach { ls }
|
||||||
|
BlockExpression: Expression = {
|
||||||
<l: @L> "{" <expr: SingleExpression> "}" <r: @R> => ExpressionBuilder::spanned_block(expr, l, r),
|
<l: @L> "{" <expr: SingleExpression> "}" <r: @R> => ExpressionBuilder::spanned_block(expr, l, r),
|
||||||
<l: @L> "{" <bare: BareExpression> "}" <r: @R> => {
|
<l: @L> "{" <bare: BareExpression> "}" <r: @R> => {
|
||||||
let call = ExpressionBuilder::spanned_call(bare.clone(), bare.span.start, bare.span.end);
|
let call = ExpressionBuilder::spanned_call(bare.clone(), bare.span.start, bare.span.end);
|
||||||
|
@ -69,7 +150,7 @@ Block: Expression = {
|
||||||
// even as the first part of a call.
|
// even as the first part of a call.
|
||||||
MemberHeadExpression: Expression = {
|
MemberHeadExpression: Expression = {
|
||||||
<LeafExpression> => <>,
|
<LeafExpression> => <>,
|
||||||
<Block> => <>,
|
<BlockExpression> => <>,
|
||||||
<l: @L> "(" <expr: Call> ")" <r: @R> => ExpressionBuilder::spanned_call(expr, l, r),
|
<l: @L> "(" <expr: Call> ")" <r: @R> => ExpressionBuilder::spanned_call(expr, l, r),
|
||||||
<l: @L> "(" <expr: BareExpression> ")" <r: @R> => ExpressionBuilder::spanned_call((expr, vec![]), l, r),
|
<l: @L> "(" <expr: BareExpression> ")" <r: @R> => ExpressionBuilder::spanned_call((expr, vec![]), l, r),
|
||||||
<l: @L> "(" <expr:Binary> ")" <r: @R> => ExpressionBuilder::spanned_parens(expr, l, r),
|
<l: @L> "(" <expr:Binary> ")" <r: @R> => ExpressionBuilder::spanned_parens(expr, l, r),
|
||||||
|
@ -77,7 +158,7 @@ MemberHeadExpression: Expression = {
|
||||||
|
|
||||||
Expression: Expression = {
|
Expression: Expression = {
|
||||||
<MemberHeadExpression> => <>,
|
<MemberHeadExpression> => <>,
|
||||||
<l: @L> <expr:MemberHeadExpression> <rest: ( "???." <"member"> )+> <r: @R> => ExpressionBuilder::spanned_path((expr, rest.iter().map(|i| i.to_spanned_string()).collect()), l, r),
|
<l: @L> <expr:MemberHeadExpression> <rest: ( "???." <Member> )+> <r: @R> => ExpressionBuilder::spanned_path((expr, rest), l, r),
|
||||||
}
|
}
|
||||||
|
|
||||||
// An `ArgumentExpression` is an expression that appears in an argument list. It includes all of `Expression`, and
|
// An `ArgumentExpression` is an expression that appears in an argument list. It includes all of `Expression`, and
|
||||||
|
@ -117,6 +198,14 @@ SpannedOperator: Spanned<Operator> = {
|
||||||
<l: @L> <op: Operator> <r: @R> => Spanned::from_item(op, Span::from((l, r)))
|
<l: @L> <op: Operator> <r: @R> => Spanned::from_item(op, Span::from((l, r)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Newlines: () = {
|
||||||
|
("newline")+
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionalNewlines: () = {
|
||||||
|
("newline")*
|
||||||
|
}
|
||||||
|
|
||||||
// === LOGICAL TOKENS === //
|
// === LOGICAL TOKENS === //
|
||||||
|
|
||||||
// A logical token may be composed of more than one raw token, but the tokens must be emitted
|
// A logical token may be composed of more than one raw token, but the tokens must be emitted
|
||||||
|
@ -129,12 +218,18 @@ Bare: Bare = {
|
||||||
|
|
||||||
// A member is a special token that represents bare words or string literals immediate
|
// A member is a special token that represents bare words or string literals immediate
|
||||||
// following a dot.
|
// following a dot.
|
||||||
Member: String = {
|
Member: Spanned<String> = {
|
||||||
<"member"> => <>.to_string(),
|
<"member"> => <>.to_spanned_string(),
|
||||||
<"dqmember"> => <>.to_string(),
|
<"dqmember"> => <>.to_spanned_string(),
|
||||||
<"sqmember"> => <>.to_string(),
|
<"sqmember"> => <>.to_spanned_string(),
|
||||||
|
<"function"> => <>.to_spanned_string(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandName: Spanned<Bare> = {
|
||||||
|
<l: @L> <name: "command-name"> <r: @R> => Spanned::from_item(Bare::from_string(name.as_slice()), (l, r)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Operator: Operator = {
|
Operator: Operator = {
|
||||||
"==" => Operator::Equal,
|
"==" => Operator::Equal,
|
||||||
"!=" => Operator::NotEqual,
|
"!=" => Operator::NotEqual,
|
||||||
|
@ -166,11 +261,42 @@ Var: Expression = {
|
||||||
<l: @L> "$" <v: "variable"> <r: @R> => ExpressionBuilder::spanned_var(v.as_slice(), l, r),
|
<l: @L> "$" <v: "variable"> <r: @R> => ExpressionBuilder::spanned_var(v.as_slice(), l, r),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpannedBare: Spanned<Bare> = {
|
||||||
|
<l: @L> <bare: Bare> <r: @R> => Spanned::from_item(bare, (l, r)),
|
||||||
|
}
|
||||||
|
|
||||||
|
// === MACROS === //
|
||||||
|
|
||||||
|
Comma<T>: Vec<T> = { // (1)
|
||||||
|
<v:(<T> OptionalNewlines "," OptionalNewlines)*> <e:T?> => match e { // (2)
|
||||||
|
None => v,
|
||||||
|
Some(e) => {
|
||||||
|
let mut v = v;
|
||||||
|
v.push(e);
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
type Location = usize;
|
type Location = usize;
|
||||||
type Error = ShellError;
|
type Error = ShellError;
|
||||||
|
|
||||||
enum SpannedToken<'input> {
|
enum SpannedToken<'input> {
|
||||||
|
"any" => SpannedToken { token: Token::TyAny, .. },
|
||||||
|
"int" => SpannedToken { token: Token::TyInt, .. },
|
||||||
|
"decimal" => SpannedToken { token: Token::TyDecimal, .. },
|
||||||
|
"bytes" => SpannedToken { token: Token::TyBytes, .. },
|
||||||
|
"text" => SpannedToken { token: Token::TyText, .. },
|
||||||
|
"boolean" => SpannedToken { token: Token::TyBoolean, .. },
|
||||||
|
"date" => SpannedToken { token: Token::TyDate, .. },
|
||||||
|
"object" => SpannedToken { token: Token::TyObject, .. },
|
||||||
|
"list" => SpannedToken { token: Token::TyList, .. },
|
||||||
|
"block" => SpannedToken { token: Token::TyBlock, .. },
|
||||||
|
|
||||||
|
"->" => SpannedToken { token: Token::ReturnArrow, .. },
|
||||||
|
"," => SpannedToken { token: Token::Comma, .. },
|
||||||
|
":" => SpannedToken { token: Token::Colon, .. },
|
||||||
"|" => SpannedToken { token: Token::Pipe, .. },
|
"|" => SpannedToken { token: Token::Pipe, .. },
|
||||||
"(" => SpannedToken { token: Token::OpenParen, .. },
|
"(" => SpannedToken { token: Token::OpenParen, .. },
|
||||||
")" => SpannedToken { token: Token::CloseParen, .. },
|
")" => SpannedToken { token: Token::CloseParen, .. },
|
||||||
|
@ -186,6 +312,9 @@ extern {
|
||||||
"--" => SpannedToken { token: Token::DashDash, .. },
|
"--" => SpannedToken { token: Token::DashDash, .. },
|
||||||
"$" => SpannedToken { token: Token::Dollar, .. },
|
"$" => SpannedToken { token: Token::Dollar, .. },
|
||||||
"???." => SpannedToken { token: Token::PathDot, .. },
|
"???." => SpannedToken { token: Token::PathDot, .. },
|
||||||
|
"command-name" => SpannedToken { token: Token::CommandName, .. },
|
||||||
|
"start-params" => SpannedToken { token: Token::StartParamList, .. },
|
||||||
|
"end-params" => SpannedToken { token: Token::EndParamList, .. },
|
||||||
"num" => SpannedToken { token: Token::Num, .. },
|
"num" => SpannedToken { token: Token::Num, .. },
|
||||||
"member" => SpannedToken { token: Token::Member, .. },
|
"member" => SpannedToken { token: Token::Member, .. },
|
||||||
"sqmember" => SpannedToken { token: Token::SQMember, .. },
|
"sqmember" => SpannedToken { token: Token::SQMember, .. },
|
||||||
|
@ -195,5 +324,7 @@ extern {
|
||||||
"dqstring" => SpannedToken { token: Token::DQString, .. },
|
"dqstring" => SpannedToken { token: Token::DQString, .. },
|
||||||
"sqstring" => SpannedToken { token: Token::SQString, .. },
|
"sqstring" => SpannedToken { token: Token::SQString, .. },
|
||||||
"unit" => SpannedToken { token: Token::Unit, .. },
|
"unit" => SpannedToken { token: Token::Unit, .. },
|
||||||
|
"newline" => SpannedToken { token: Token::Newline, .. },
|
||||||
|
"function" => SpannedToken { token: Token::KeywordFunction, .. },
|
||||||
}
|
}
|
||||||
}
|
}
|
15435
src/parser/parser.rs
15435
src/parser/parser.rs
File diff suppressed because it is too large
Load diff
|
@ -1 +1 @@
|
||||||
S
|
"S"
|
||||||
|
|
Loading…
Reference in a new issue