mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-28 04:35:33 +03:00
merge master
This commit is contained in:
commit
e10a1e1be0
2
.cargo/config
Normal file
2
.cargo/config
Normal file
@ -0,0 +1,2 @@
|
||||
[build]
|
||||
rustflags = ["-C", "target-cpu=native"]
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,7 +1,4 @@
|
||||
/target
|
||||
**.idea/
|
||||
Leo.toml
|
||||
src/
|
||||
inputs/
|
||||
outputs/
|
||||
*.DS_Store
|
||||
|
317
Cargo.lock
generated
317
Cargo.lock
generated
@ -99,13 +99,14 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.7.1"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b77e29dbd0115e43938be2d5128ecf81c0353e00acaa65339a1242586951d9"
|
||||
checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
|
||||
dependencies = [
|
||||
"byte-tools 0.2.0",
|
||||
"byte-tools",
|
||||
"crypto-mac",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -115,9 +116,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools 0.3.1",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.3",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -126,15 +127,9 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools 0.3.1",
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
@ -208,12 +203,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
@ -263,32 +252,53 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.5.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958"
|
||||
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
dependencies = [
|
||||
"constant_time_eq",
|
||||
"generic-array 0.9.0",
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "762e34611d2d5233a506a79072be944fddd057db2f18e04c0d6fa79e3fd466fd"
|
||||
dependencies = [
|
||||
"curl-sys",
|
||||
"libc",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"socket2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.4.31+curl-7.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcd62757cc4f5ab9404bc6ca9f0ae447e729a1403948ce5106bd588ceac6a3b0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "1.0.4"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c6d883546668a3e2011b6a716a7330b82eabb0151b138217f632c8243e17135"
|
||||
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||
dependencies = [
|
||||
"generic-array 0.9.0",
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -297,7 +307,7 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -363,15 +373,6 @@ version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
@ -398,15 +399,6 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.8"
|
||||
@ -448,9 +440,9 @@ checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-core"
|
||||
version = "14.1.0"
|
||||
version = "14.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25525f6002338fb4debb5167a89a0b47f727a5a48418417545ad3429758b7fec"
|
||||
checksum = "a0747307121ffb9703afd93afbd0fb4f854c38fb873f2c8b90e0e902f27c7b62"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"log",
|
||||
@ -478,7 +470,6 @@ dependencies = [
|
||||
"clap",
|
||||
"colored",
|
||||
"env_logger",
|
||||
"failure",
|
||||
"from-pest",
|
||||
"leo-compiler",
|
||||
"leo-inputs",
|
||||
@ -493,36 +484,31 @@ dependencies = [
|
||||
"snarkos-gadgets",
|
||||
"snarkos-models",
|
||||
"snarkos-utilities",
|
||||
"structopt",
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-benchmark"
|
||||
name = "leo-ast"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"leo-compiler",
|
||||
"rand",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
"snarkos-errors",
|
||||
"snarkos-gadgets",
|
||||
"snarkos-models",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"pest",
|
||||
"pest-ast",
|
||||
"pest_derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-compiler"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"failure",
|
||||
"from-pest",
|
||||
"hex",
|
||||
"lazy_static",
|
||||
"leo-ast",
|
||||
"leo-types",
|
||||
"log",
|
||||
"pest",
|
||||
"pest-ast",
|
||||
"pest_derive",
|
||||
"rand",
|
||||
"sha2",
|
||||
"snarkos-algorithms",
|
||||
@ -530,6 +516,8 @@ dependencies = [
|
||||
"snarkos-errors",
|
||||
"snarkos-gadgets",
|
||||
"snarkos-models",
|
||||
"snarkos-utilities",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -548,6 +536,16 @@ dependencies = [
|
||||
"snarkos-models",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"leo-ast",
|
||||
"snarkos-errors",
|
||||
"snarkos-models",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.67"
|
||||
@ -576,6 +574,18 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
@ -638,6 +648,25 @@ version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7410fef80af8ac071d4f63755c0ab89ac3df0fd1ea91f1d1f37cf5cec4395990"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
@ -700,38 +729,18 @@ dependencies = [
|
||||
"sha-1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
"syn-mid",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
@ -848,6 +857,12 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.4"
|
||||
@ -894,6 +909,16 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@ -938,7 +963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest 0.8.1",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
@ -950,7 +975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest 0.8.1",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
@ -982,8 +1007,9 @@ version = "0.8.0"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rayon",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
@ -1009,10 +1035,11 @@ name = "snarkos-errors"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"failure",
|
||||
"curl",
|
||||
"hex",
|
||||
"jsonrpc-core",
|
||||
"rocksdb",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1020,7 +1047,7 @@ name = "snarkos-gadgets"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
"snarkos-errors",
|
||||
@ -1033,7 +1060,6 @@ name = "snarkos-models"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"failure",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"smallvec",
|
||||
@ -1052,6 +1078,18 @@ dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
@ -1059,28 +1097,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.14"
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
]
|
||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
@ -1104,17 +1124,6 @@ dependencies = [
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn-mid"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.3"
|
||||
@ -1145,6 +1154,26 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
@ -1175,12 +1204,6 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.7"
|
||||
@ -1199,6 +1222,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.1"
|
||||
|
@ -13,7 +13,7 @@ name = "leo"
|
||||
path = "leo/main.rs"
|
||||
|
||||
[workspace]
|
||||
members = [ "benchmark", "compiler", "leo-inputs" ]
|
||||
members = [ "ast", "compiler", "types" ]
|
||||
|
||||
[dependencies]
|
||||
leo-compiler = { path = "compiler", version = "0.1.0" }
|
||||
@ -23,18 +23,17 @@ snarkos-algorithms = { path = "../snarkOS/algorithms", version = "0.8.0" }
|
||||
snarkos-curves = { path = "../snarkOS/curves", version = "0.8.0" }
|
||||
snarkos-errors = { path = "../snarkOS/errors", version = "0.8.0" }
|
||||
snarkos-gadgets = { path = "../snarkOS/gadgets", version = "0.8.0" }
|
||||
snarkos-models = { path = "../snarkOS/models", version = "0.8.0" }
|
||||
snarkos-models = { path = "../snarkOS/models", version = "0.8.0" }
|
||||
snarkos-utilities = { path = "../snarkOS/utilities", version = "0.8.0" }
|
||||
|
||||
clap = { version = "2.33.0" }
|
||||
colored = { version = "1.9" }
|
||||
env_logger = { version = "0.7" }
|
||||
failure = { version = "0.1.5" }
|
||||
from-pest = { version = "0.3.1" }
|
||||
log = { version = "0.4" }
|
||||
rand = { version = "0.7" }
|
||||
rand_core = { version = "0.5.1" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0" }
|
||||
structopt = { version = "0.3.14" }
|
||||
toml = { version = "0.5" }
|
||||
thiserror = { version = "1.0" }
|
||||
|
332
README.md
332
README.md
@ -1,41 +1,87 @@
|
||||
# The Leo Language
|
||||
* All code examples can be copied and pasted into `main.leo` directly and executed with cargo run
|
||||
# The Leo Programming Language
|
||||
* Programs should be formatted:
|
||||
1. Import definitions
|
||||
2. Struct definitions
|
||||
2. Circuit definitions
|
||||
3. Function definitions
|
||||
|
||||
### Integers:
|
||||
Currently, all integers are parsed as u32.
|
||||
You can choose to explicitly add the type or let the compiler interpret implicitly.
|
||||
## Mutability
|
||||
* All defined variables in Leo are immutable by default.
|
||||
* Variables can be made mutable with the `mut` keyword.
|
||||
|
||||
```rust
|
||||
function main() -> u32 {
|
||||
let a : u32 = 1u32 + 1u32; // explicit type
|
||||
let b = 1 - 1; // implicit type
|
||||
let c = 2 * 2;
|
||||
let d = 4 / 2;
|
||||
let e = 2 ** 3;
|
||||
function main() {
|
||||
let a = 0u32;
|
||||
//a = 1 <- Will fail
|
||||
|
||||
let mut b = 0u32;
|
||||
b = 1; // <- Ok
|
||||
}
|
||||
```
|
||||
|
||||
## Booleans
|
||||
|
||||
Explicit types are optional.
|
||||
```rust
|
||||
function main() -> bool {
|
||||
let a: bool = true || false;
|
||||
let b = false && false;
|
||||
let c = 1u32 == 1u32;
|
||||
return a
|
||||
}
|
||||
```
|
||||
|
||||
### Field Elements:
|
||||
Field elements must have the type added explicitly.
|
||||
## Numbers
|
||||
* The definition of a number must include an explict type.
|
||||
* After assignment, you can choose to explicitly add the type or let the compiler interpret implicitly.
|
||||
* Type casting is not supported.
|
||||
* Comparators are not supported.
|
||||
|
||||
### Integers
|
||||
Supported integer types: `u8`, `u16`, `u32`, `u64`, `u128`
|
||||
```rust
|
||||
function main() -> fe {
|
||||
let f : fe = 21888242871839275222246405745257275088548364400416034343698204186575808495617fe;
|
||||
let a = 1fe + 1fe;
|
||||
let b = 1fe - 1fe;
|
||||
let c = 2fe * 2fe;
|
||||
let d = 4fe / 2fe;
|
||||
return a
|
||||
function main() -> u32 {
|
||||
let a = 2u32; // explicit type
|
||||
let a: u32 = 1 + 1; // explicit type
|
||||
|
||||
let b = a - 1; // implicit type
|
||||
let c = b * 4;
|
||||
let d = c / 2;
|
||||
let e = d ** 3;
|
||||
return e
|
||||
}
|
||||
```
|
||||
|
||||
### Operator Assignment Statements:
|
||||
### Field Elements
|
||||
```rust
|
||||
function main() -> field {
|
||||
let a = 1000field; // explicit type
|
||||
let a: field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // explicit type
|
||||
let b = a + 1; // implicit type
|
||||
let c = b - 1;
|
||||
let d = c * 4;
|
||||
let e = d / 2;
|
||||
return e
|
||||
}
|
||||
```
|
||||
|
||||
### Affine Points
|
||||
The set of affine points on the elliptic curve passed into the leo compiler forms a group.
|
||||
Leo supports this set as a primitive data type.
|
||||
|
||||
```rust
|
||||
function main() -> group {
|
||||
let a = 1000group; // explicit type
|
||||
let a = (21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617)group; // explicit type
|
||||
let b = a + 0; // implicit type
|
||||
let c = b - 0;
|
||||
return c
|
||||
}
|
||||
```
|
||||
|
||||
### Operator Assignment Statements
|
||||
```rust
|
||||
function main() -> u32 {
|
||||
let a = 10;
|
||||
let mut a = 10;
|
||||
a += 5;
|
||||
a -= 10;
|
||||
a *= 5;
|
||||
@ -46,30 +92,18 @@ function main() -> u32 {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Booleans:
|
||||
```rust
|
||||
function main() -> bool {
|
||||
let a : bool = true || false;
|
||||
let b = false && false;
|
||||
let c = 1 == 1;
|
||||
return a
|
||||
}
|
||||
```
|
||||
|
||||
### Arrays:
|
||||
## Arrays
|
||||
Leo supports static arrays with fixed length.
|
||||
Array type must be explicitly stated
|
||||
```rust
|
||||
function main() -> u32[2] {
|
||||
// initialize an integer array with integer values
|
||||
let a : u32[3] = [1, 2, 3];
|
||||
let mut a: u32[3] = [1, 2, 3];
|
||||
|
||||
// set a member to a value
|
||||
// set a mutable member to a value
|
||||
a[2] = 4;
|
||||
|
||||
// initialize an array of 4 values all equal to 42
|
||||
let b = [42; 4];
|
||||
let b = [42u8; 4];
|
||||
|
||||
// initialize an array of 5 values copying all elements of b using a spread
|
||||
let c = [1, ...b];
|
||||
@ -78,63 +112,42 @@ function main() -> u32[2] {
|
||||
let d = c[1..3];
|
||||
|
||||
// initialize a field array
|
||||
let e = [5fe; 2];
|
||||
let e = [5field; 2];
|
||||
|
||||
// initialize a boolean array
|
||||
let f = [true, false || true, true];
|
||||
|
||||
// return an array
|
||||
return d
|
||||
}
|
||||
```
|
||||
### Structs:
|
||||
|
||||
### Multidimensional Arrays
|
||||
```rust
|
||||
struct Point {
|
||||
u32 x
|
||||
u32 y
|
||||
}
|
||||
function main() -> u32 {
|
||||
Point p = Point {x: 1, y: 0}
|
||||
return p.x
|
||||
}
|
||||
```
|
||||
```rust
|
||||
struct Foo {
|
||||
bool x
|
||||
}
|
||||
function main() -> Foo {
|
||||
let f = Foo {x: true};
|
||||
f.x = false;
|
||||
return f
|
||||
function main() -> u32[3][2] {
|
||||
let m = [[0u32, 0u32], [0u32, 0u32]];
|
||||
|
||||
let m: u32[3][2] = [[0; 3]; 2];
|
||||
|
||||
return m
|
||||
}
|
||||
```
|
||||
|
||||
### Assert Equals:
|
||||
This will enforce that the two values are equal in the constraint system.
|
||||
## Conditionals
|
||||
|
||||
```rust
|
||||
function main() {
|
||||
assert_eq(45, 45);
|
||||
|
||||
assert_eq(2fe, 2fe);
|
||||
|
||||
assert_eq(true, true);
|
||||
}
|
||||
```
|
||||
|
||||
### Conditionals:
|
||||
|
||||
#### If Else Ternary Expression
|
||||
### If Else Ternary Expression
|
||||
```rust
|
||||
function main() -> u32 {
|
||||
let y = if 3==3 ? 1 : 5;
|
||||
return y
|
||||
}
|
||||
```
|
||||
#### If Else Conditional Statement
|
||||
|
||||
### If Else Conditional Statement
|
||||
** **Experimental** **
|
||||
The current constraint system is not optimized for statement branching. Please use the ternary expression above until this feature is stable.
|
||||
```rust
|
||||
function main(a: private bool, b: private bool) -> u32 {
|
||||
let res = 0;
|
||||
let mut res = 0u32;
|
||||
if (a) {
|
||||
res = 1;
|
||||
} else if (b) {
|
||||
@ -145,25 +158,26 @@ function main(a: private bool, b: private bool) -> u32 {
|
||||
return res
|
||||
}
|
||||
```
|
||||
#### For loop
|
||||
|
||||
### For loop
|
||||
```rust
|
||||
function main() -> fe {
|
||||
let a = 1fe;
|
||||
let mut a = 1field;
|
||||
for i in 0..4 {
|
||||
a = a + 1fe;
|
||||
a = a + 1;
|
||||
}
|
||||
return a
|
||||
}
|
||||
```
|
||||
|
||||
### Functions:
|
||||
## Functions
|
||||
```rust
|
||||
function test1(a : u32) -> u32 {
|
||||
return a + 1
|
||||
}
|
||||
|
||||
function test2(b: fe) -> fe {
|
||||
return b * 2fe
|
||||
function test2(b: fe) -> field {
|
||||
return b * 2field
|
||||
}
|
||||
|
||||
function test3(c: bool) -> bool {
|
||||
@ -176,20 +190,20 @@ function main() -> u32 {
|
||||
```
|
||||
|
||||
|
||||
#### Function Scope:
|
||||
### Function Scope
|
||||
```rust
|
||||
function foo() -> field {
|
||||
// return myGlobal <- not allowed
|
||||
return 42fe
|
||||
return 42field
|
||||
}
|
||||
|
||||
function main() -> field {
|
||||
let myGlobal = 42fe;
|
||||
let myGlobal = 42field;
|
||||
return foo()
|
||||
}
|
||||
```
|
||||
|
||||
#### Multiple returns:
|
||||
### Multiple returns
|
||||
Functions can return tuples whose types are specified in the function signature.
|
||||
```rust
|
||||
function test() -> (u32, u32[2]) {
|
||||
@ -198,26 +212,32 @@ function test() -> (u32, u32[2]) {
|
||||
|
||||
function main() -> u32[3] {
|
||||
let (a, b) = test();
|
||||
// a, u32[2] b = test() <- explicit type also works
|
||||
// (a, u32[2] b) = test() <- explicit type also works
|
||||
return [a, ...b]
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters:
|
||||
Main function arguments are allocated as public or private variables in the program's constaint system.
|
||||
### Main function inputs
|
||||
Main function inputs are allocated as public or private variables in the program's constaint system.
|
||||
```rust
|
||||
function main(a: private fe) -> fe {
|
||||
function main(a: private field) -> field {
|
||||
return a
|
||||
}
|
||||
```
|
||||
```rust
|
||||
function main(a: public fe) -> fe {
|
||||
function main(a: public field) -> field {
|
||||
return a
|
||||
}
|
||||
```
|
||||
Function parameters are passed by value.
|
||||
Private by default. Below `a` is implicitly private.
|
||||
```rust
|
||||
function test(a: u32) {
|
||||
function main(a: field) -> field {
|
||||
return a
|
||||
}
|
||||
```
|
||||
Function inputs are passed by value.
|
||||
```rust
|
||||
function test(mut a: u32) {
|
||||
a = 0;
|
||||
}
|
||||
|
||||
@ -229,17 +249,76 @@ function main() -> u32 {
|
||||
}
|
||||
```
|
||||
|
||||
### Imports:
|
||||
## Circuits
|
||||
Circuits in Leo are similar to classes in object oriented langauges. Circuits are defined above functions in a Leo program. Circuits can have one or more members.
|
||||
|
||||
|
||||
Members can be defined as fields which hold primitive values
|
||||
```rust
|
||||
circuit Point {
|
||||
x: u32
|
||||
y: u32
|
||||
}
|
||||
function main() -> u32 {
|
||||
let p = Point {x: 1, y: 0};
|
||||
return p.x
|
||||
}
|
||||
```
|
||||
|
||||
Members can also be defined as functions.
|
||||
```rust
|
||||
circuit Circ {
|
||||
function echo(x: u32) -> u32 {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
function main() -> u32 {
|
||||
let c = Circ { };
|
||||
return c.echo(1u32)
|
||||
}
|
||||
```
|
||||
|
||||
Circuit functions can be made static, enabling them to be called without instantiation.
|
||||
```rust
|
||||
circuit Circ {
|
||||
static function echo(x: u32) -> u32 {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
function main() -> u32 {
|
||||
return Circ::echo(1u32)
|
||||
}
|
||||
```
|
||||
|
||||
The `Self` keyword is supported in circuit functions.
|
||||
```rust
|
||||
circuit Circ {
|
||||
b: bool
|
||||
|
||||
static function new() -> Self {
|
||||
return Self { b: true }
|
||||
}
|
||||
}
|
||||
|
||||
function main() -> Circ {
|
||||
let c = Circ::new();
|
||||
return c.b
|
||||
}
|
||||
```
|
||||
|
||||
## Imports
|
||||
Both struct and function imports are supported.
|
||||
|
||||
import all: `*`
|
||||
import alias: `symbol as alias`
|
||||
|
||||
/simple_import.leo
|
||||
`src/simple_import.leo`
|
||||
```rust
|
||||
struct Point {
|
||||
u32 x
|
||||
u32 y
|
||||
circuit Point {
|
||||
x: u32
|
||||
y: u32
|
||||
}
|
||||
|
||||
function test() -> (u32, u32[2]) {
|
||||
@ -247,7 +326,7 @@ function test() -> (u32, u32[2]) {
|
||||
}
|
||||
```
|
||||
|
||||
/simple.leo
|
||||
`src/simple.leo`
|
||||
```rust
|
||||
from "./simple_import" import {
|
||||
Point as Foo,
|
||||
@ -257,12 +336,50 @@ from "./simple_import" import {
|
||||
// from "./simple_import" import *
|
||||
|
||||
function main() -> (u32[3]) {
|
||||
let (a, b) = test();
|
||||
let p = Foo { x: 1, y: 2};
|
||||
|
||||
let (a, b) = test();
|
||||
|
||||
return [a, ...b]
|
||||
}
|
||||
```
|
||||
|
||||
## Constraints
|
||||
|
||||
### Assert Equals
|
||||
This will enforce that the two values are equal in the constraint system.
|
||||
|
||||
```rust
|
||||
function main() {
|
||||
assert_eq(45, 45);
|
||||
|
||||
assert_eq(2fe, 2fe);
|
||||
|
||||
assert_eq(true, true);
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Use the `test` keyword to add tests to a leo program. Tests must have 0 function inputs and 0 function returns.
|
||||
|
||||
```rust
|
||||
function main(a: u32) -> u32 {
|
||||
return a
|
||||
}
|
||||
|
||||
test function expect_pass() {
|
||||
let a = 1u32;
|
||||
|
||||
let res = main(a);
|
||||
|
||||
assert_eq!(res, 1u32);
|
||||
}
|
||||
|
||||
test function expect_fail() {
|
||||
assert_eq!(1u8, 0u8);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# Leo CLI
|
||||
@ -283,7 +400,7 @@ This will create a new directory with a given package name. The new package will
|
||||
- lib.leo # Your program library
|
||||
- main.leo # Your program
|
||||
- tests
|
||||
- tests.leo # Your program tests
|
||||
- test.leo # Your program tests
|
||||
- Leo.toml # Your program manifest
|
||||
```
|
||||
|
||||
@ -308,6 +425,12 @@ To execute unit tests on your program, run:
|
||||
```
|
||||
leo test
|
||||
```
|
||||
The results of test compilation and the constraint system will be printed:
|
||||
```
|
||||
INFO leo Running 2 tests
|
||||
INFO leo test language::expect_pass compiled. Constraint system satisfied: true
|
||||
ERROR leo test language::expect_fail errored: Assertion 1u8 == 0u8 failed
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
@ -377,6 +500,13 @@ To deploy your program to Aleo, run:
|
||||
leo deploy
|
||||
```
|
||||
|
||||
# Install
|
||||
|
||||
To install Leo from source, in the root directory of the repository, run:
|
||||
```
|
||||
cargo install --path .
|
||||
```
|
||||
|
||||
## TODO
|
||||
|
||||
- Change `target` directory to some other directory to avoid collision.
|
||||
|
14
ast/Cargo.toml
Normal file
14
ast/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "leo-ast"
|
||||
version = "0.1.0"
|
||||
authors = ["The Aleo Team <hello@aleo.org>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
from-pest = { version = "0.3.1" }
|
||||
lazy_static = { version = "1.3.0" }
|
||||
log = { version = "0.4" }
|
||||
pest = { version = "2.0" }
|
||||
pest-ast = { version = "0.3.3" }
|
||||
pest_derive = { version = "2.0" }
|
||||
thiserror = { version = "1.0" }
|
1
ast/README.md
Normal file
1
ast/README.md
Normal file
@ -0,0 +1 @@
|
||||
# leo-ast
|
12
ast/src/access/access.rs
Normal file
12
ast/src/access/access.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{access::*, ast::Rule};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::access))]
|
||||
pub enum Access<'ast> {
|
||||
Array(ArrayAccess<'ast>),
|
||||
Call(CallAccess<'ast>),
|
||||
Object(MemberAccess<'ast>),
|
||||
StaticObject(StaticMemberAccess<'ast>),
|
||||
}
|
12
ast/src/access/array_access.rs
Normal file
12
ast/src/access/array_access.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, common::RangeOrExpression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::access_array))]
|
||||
pub struct ArrayAccess<'ast> {
|
||||
pub expression: RangeOrExpression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
20
ast/src/access/assignee_access.rs
Normal file
20
ast/src/access/assignee_access.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{access::{ArrayAccess, MemberAccess}, ast::Rule};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::access_assignee))]
|
||||
pub enum AssigneeAccess<'ast> {
|
||||
Array(ArrayAccess<'ast>),
|
||||
Member(MemberAccess<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for AssigneeAccess<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
AssigneeAccess::Array(ref array) => write!(f, "[{}]", array.expression),
|
||||
AssigneeAccess::Member(ref member) => write!(f, ".{}", member.identifier),
|
||||
}
|
||||
}
|
||||
}
|
12
ast/src/access/call_access.rs
Normal file
12
ast/src/access/call_access.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::access_call))]
|
||||
pub struct CallAccess<'ast> {
|
||||
pub expressions: Vec<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
12
ast/src/access/member_access.rs
Normal file
12
ast/src/access/member_access.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::access_member))]
|
||||
pub struct MemberAccess<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
17
ast/src/access/mod.rs
Normal file
17
ast/src/access/mod.rs
Normal file
@ -0,0 +1,17 @@
|
||||
pub mod access;
|
||||
pub use access::*;
|
||||
|
||||
pub mod array_access;
|
||||
pub use array_access::*;
|
||||
|
||||
pub mod assignee_access;
|
||||
pub use assignee_access::*;
|
||||
|
||||
pub mod call_access;
|
||||
pub use call_access::*;
|
||||
|
||||
pub mod member_access;
|
||||
pub use member_access::*;
|
||||
|
||||
pub mod static_member_access;
|
||||
pub use static_member_access::*;
|
12
ast/src/access/static_member_access.rs
Normal file
12
ast/src/access/static_member_access.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::access_static_member))]
|
||||
pub struct StaticMemberAccess<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
173
ast/src/ast.rs
Normal file
173
ast/src/ast.rs
Normal file
@ -0,0 +1,173 @@
|
||||
//! Abstract syntax tree (ast) representation from leo.pest.
|
||||
use crate::{
|
||||
common::Identifier,
|
||||
expressions::{
|
||||
ArrayInlineExpression,
|
||||
ArrayInitializerExpression,
|
||||
CircuitInlineExpression,
|
||||
Expression,
|
||||
TernaryExpression,
|
||||
NotExpression,
|
||||
PostfixExpression
|
||||
},
|
||||
operations::{
|
||||
BinaryOperation,
|
||||
NotOperation,
|
||||
},
|
||||
values::Value,
|
||||
};
|
||||
|
||||
use from_pest::{ConversionError, FromPest, Void};
|
||||
use pest::{
|
||||
error::Error,
|
||||
iterators::{Pair, Pairs},
|
||||
prec_climber::{Assoc, Operator, PrecClimber},
|
||||
Parser, Span,
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "leo.pest"]
|
||||
pub struct LanguageParser;
|
||||
|
||||
pub fn parse(input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
|
||||
LanguageParser::parse(Rule::file, input)
|
||||
}
|
||||
|
||||
pub(crate) fn span_into_string(span: Span) -> String {
|
||||
span.as_str().to_string()
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref PRECEDENCE_CLIMBER: PrecClimber<Rule> = precedence_climber();
|
||||
}
|
||||
|
||||
// Expressions
|
||||
|
||||
fn precedence_climber() -> PrecClimber<Rule> {
|
||||
PrecClimber::new(vec![
|
||||
Operator::new(Rule::operation_or, Assoc::Left),
|
||||
Operator::new(Rule::operation_and, Assoc::Left),
|
||||
Operator::new(Rule::operation_eq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_ne, Assoc::Left),
|
||||
Operator::new(Rule::operation_ge, Assoc::Left)
|
||||
| Operator::new(Rule::operation_gt, Assoc::Left)
|
||||
| Operator::new(Rule::operation_le, Assoc::Left)
|
||||
| Operator::new(Rule::operation_lt, Assoc::Left),
|
||||
Operator::new(Rule::operation_add, Assoc::Left)
|
||||
| Operator::new(Rule::operation_sub, Assoc::Left),
|
||||
Operator::new(Rule::operation_mul, Assoc::Left)
|
||||
| Operator::new(Rule::operation_div, Assoc::Left),
|
||||
Operator::new(Rule::operation_pow, Assoc::Left),
|
||||
])
|
||||
}
|
||||
|
||||
fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::expression_term => {
|
||||
let clone = pair.clone();
|
||||
let next = clone.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
||||
Rule::expression_array_inline => {
|
||||
Expression::ArrayInline(
|
||||
ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::expression_array_initializer => {
|
||||
Expression::ArrayInitializer(
|
||||
ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::expression_circuit_inline => {
|
||||
Expression::CircuitInline(
|
||||
CircuitInlineExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Rule::expression_conditional => {
|
||||
Expression::Ternary(
|
||||
TernaryExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Rule::expression_not => {
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_not => NotOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
|
||||
};
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
Expression::Not(NotExpression { operation, expression, span })
|
||||
},
|
||||
Rule::expression_postfix => {
|
||||
Expression::Postfix(
|
||||
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
}
|
||||
Rule::expression_primitive => {
|
||||
let next = next.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::value => {
|
||||
Expression::Value(
|
||||
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::identifier => Expression::Identifier(
|
||||
Identifier::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
),
|
||||
rule => unreachable!("`expression_primitive` should contain one of [`value`, `identifier`], found {:#?}", rule)
|
||||
}
|
||||
},
|
||||
rule => unreachable!("`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
|
||||
}
|
||||
}
|
||||
rule => unreachable!(
|
||||
"`parse_expression_term` should be invoked on `Rule::expression_term`, found {:#?}",
|
||||
rule
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
fn binary_expression<'ast>(
|
||||
lhs: Box<Expression<'ast>>,
|
||||
pair: Pair<'ast, Rule>,
|
||||
rhs: Box<Expression<'ast>>,
|
||||
) -> Box<Expression<'ast>> {
|
||||
let (start, _) = lhs.span().clone().split();
|
||||
let (_, end) = rhs.span().clone().split();
|
||||
let span = start.span(&end);
|
||||
|
||||
Box::new(match pair.as_rule() {
|
||||
Rule::operation_or => Expression::binary(BinaryOperation::Or, lhs, rhs, span),
|
||||
Rule::operation_and => Expression::binary(BinaryOperation::And, lhs, rhs, span),
|
||||
Rule::operation_eq => Expression::binary(BinaryOperation::Eq, lhs, rhs, span),
|
||||
Rule::operation_ne => Expression::binary(BinaryOperation::Ne, lhs, rhs, span),
|
||||
Rule::operation_ge => Expression::binary(BinaryOperation::Ge, lhs, rhs, span),
|
||||
Rule::operation_gt => Expression::binary(BinaryOperation::Gt, lhs, rhs, span),
|
||||
Rule::operation_le => Expression::binary(BinaryOperation::Le, lhs, rhs, span),
|
||||
Rule::operation_lt => Expression::binary(BinaryOperation::Lt, lhs, rhs, span),
|
||||
Rule::operation_add => Expression::binary(BinaryOperation::Add, lhs, rhs, span),
|
||||
Rule::operation_sub => Expression::binary(BinaryOperation::Sub, lhs, rhs, span),
|
||||
Rule::operation_mul => Expression::binary(BinaryOperation::Mul, lhs, rhs, span),
|
||||
Rule::operation_div => Expression::binary(BinaryOperation::Div, lhs, rhs, span),
|
||||
Rule::operation_pow => Expression::binary(BinaryOperation::Pow, lhs, rhs, span),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
||||
impl<'ast> FromPest<'ast> for Expression<'ast> {
|
||||
type Rule = Rule;
|
||||
type FatalError = Void;
|
||||
|
||||
fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result<Self, ConversionError<Void>> {
|
||||
let mut clone = pest.clone();
|
||||
let pair = clone.next().ok_or(::from_pest::ConversionError::NoMatch)?;
|
||||
match pair.as_rule() {
|
||||
Rule::expression => {
|
||||
// Transfer iterated state to pest.
|
||||
*pest = clone;
|
||||
Ok(*PRECEDENCE_CLIMBER.climb(pair.into_inner(), parse_term, binary_expression))
|
||||
}
|
||||
_ => Err(ConversionError::NoMatch),
|
||||
}
|
||||
}
|
||||
}
|
13
ast/src/circuits/circuit.rs
Normal file
13
ast/src/circuits/circuit.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, circuits::CircuitMember, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::circuit_definition))]
|
||||
pub struct Circuit<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub members: Vec<CircuitMember<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/circuits/circuit_field.rs
Normal file
13
ast/src/circuits/circuit_field.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, common::Identifier, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::circuit_field))]
|
||||
pub struct CircuitField<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub expression: Expression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/circuits/circuit_field_definition.rs
Normal file
13
ast/src/circuits/circuit_field_definition.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, common::Identifier, types::Type};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::circuit_field_definition))]
|
||||
pub struct CircuitFieldDefinition<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub _type: Type<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/circuits/circuit_function.rs
Normal file
13
ast/src/circuits/circuit_function.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, common::Static, functions::Function};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::circuit_function))]
|
||||
pub struct CircuitFunction<'ast> {
|
||||
pub _static: Option<Static>,
|
||||
pub function: Function<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
10
ast/src/circuits/circuit_member.rs
Normal file
10
ast/src/circuits/circuit_member.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::{ast::Rule, circuits::{CircuitFunction, CircuitFieldDefinition}};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::circuit_member))]
|
||||
pub enum CircuitMember<'ast> {
|
||||
CircuitFieldDefinition(CircuitFieldDefinition<'ast>),
|
||||
CircuitFunction(CircuitFunction<'ast>),
|
||||
}
|
14
ast/src/circuits/mod.rs
Normal file
14
ast/src/circuits/mod.rs
Normal file
@ -0,0 +1,14 @@
|
||||
pub mod circuit;
|
||||
pub use circuit::*;
|
||||
|
||||
pub mod circuit_field;
|
||||
pub use circuit_field::*;
|
||||
|
||||
pub mod circuit_field_definition;
|
||||
pub use circuit_field_definition::*;
|
||||
|
||||
pub mod circuit_function;
|
||||
pub use circuit_function::*;
|
||||
|
||||
pub mod circuit_member;
|
||||
pub use circuit_member::*;
|
27
ast/src/common/assignee.rs
Normal file
27
ast/src/common/assignee.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::{access::AssigneeAccess, ast::Rule, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::assignee))]
|
||||
pub struct Assignee<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub accesses: Vec<AssigneeAccess<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Assignee<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.identifier)?;
|
||||
for (i, access) in self.accesses.iter().enumerate() {
|
||||
write!(f, "{}", access)?;
|
||||
if i < self.accesses.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
7
ast/src/common/eoi.rs
Normal file
7
ast/src/common/eoi.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::EOI))]
|
||||
pub struct EOI;
|
20
ast/src/common/identifier.rs
Normal file
20
ast/src/common/identifier.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::ast::{span_into_string, Rule};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::identifier))]
|
||||
pub struct Identifier<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Identifier<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
7
ast/src/common/line_end.rs
Normal file
7
ast/src/common/line_end.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::LINE_END))]
|
||||
pub struct LineEnd;
|
35
ast/src/common/mod.rs
Normal file
35
ast/src/common/mod.rs
Normal file
@ -0,0 +1,35 @@
|
||||
pub mod assignee;
|
||||
pub use assignee::*;
|
||||
|
||||
pub mod eoi;
|
||||
pub use eoi::*;
|
||||
|
||||
pub mod identifier;
|
||||
pub use identifier::*;
|
||||
|
||||
pub mod line_end;
|
||||
pub use line_end::*;
|
||||
|
||||
pub mod mutable;
|
||||
pub use mutable::*;
|
||||
|
||||
pub mod range;
|
||||
pub use range::*;
|
||||
|
||||
pub mod range_or_expression;
|
||||
pub use range_or_expression::*;
|
||||
|
||||
pub mod spread;
|
||||
pub use spread::*;
|
||||
|
||||
pub mod spread_or_expression;
|
||||
pub use spread_or_expression::*;
|
||||
|
||||
pub mod static_;
|
||||
pub use static_::*;
|
||||
|
||||
pub mod variable;
|
||||
pub use variable::*;
|
||||
|
||||
pub mod visibility;
|
||||
pub use visibility::*;
|
7
ast/src/common/mutable.rs
Normal file
7
ast/src/common/mutable.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::mutable))]
|
||||
pub struct Mutable {}
|
21
ast/src/common/range.rs
Normal file
21
ast/src/common/range.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::{ast::Rule, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::range))]
|
||||
pub struct Range<'ast> {
|
||||
pub from: Option<FromExpression<'ast>>,
|
||||
pub to: Option<ToExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::from_expression))]
|
||||
pub struct FromExpression<'ast>(pub Expression<'ast>);
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::to_expression))]
|
||||
pub struct ToExpression<'ast>(pub Expression<'ast>);
|
33
ast/src/common/range_or_expression.rs
Normal file
33
ast/src/common/range_or_expression.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use crate::{ast::Rule, common::Range, expressions::Expression};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::range_or_expression))]
|
||||
pub enum RangeOrExpression<'ast> {
|
||||
Range(Range<'ast>),
|
||||
Expression(Expression<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for RangeOrExpression<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
RangeOrExpression::Expression(ref expression) => write!(f, "{}", expression),
|
||||
RangeOrExpression::Range(ref range) => write!(
|
||||
f,
|
||||
"{}..{}",
|
||||
range
|
||||
.from
|
||||
.as_ref()
|
||||
.map(|e| e.0.to_string())
|
||||
.unwrap_or("".to_string()),
|
||||
range
|
||||
.to
|
||||
.as_ref()
|
||||
.map(|e| e.0.to_string())
|
||||
.unwrap_or("".to_string())
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
19
ast/src/common/spread.rs
Normal file
19
ast/src/common/spread.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use crate::{ast::Rule, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::spread))]
|
||||
pub struct Spread<'ast> {
|
||||
pub expression: Expression<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Spread<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "...{}", self.expression)
|
||||
}
|
||||
}
|
20
ast/src/common/spread_or_expression.rs
Normal file
20
ast/src/common/spread_or_expression.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{ast::Rule, common::Spread, expressions::Expression};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::spread_or_expression))]
|
||||
pub enum SpreadOrExpression<'ast> {
|
||||
Spread(Spread<'ast>),
|
||||
Expression(Expression<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for SpreadOrExpression<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
SpreadOrExpression::Spread(ref spread) => write!(f, "{}", spread),
|
||||
SpreadOrExpression::Expression(ref expression) => write!(f, "{}", expression),
|
||||
}
|
||||
}
|
||||
}
|
7
ast/src/common/static_.rs
Normal file
7
ast/src/common/static_.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::static_))]
|
||||
pub struct Static {}
|
31
ast/src/common/variable.rs
Normal file
31
ast/src/common/variable.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use crate::{ast::Rule, common::{Identifier, Mutable}, types::Type};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::variable))]
|
||||
pub struct Variable<'ast> {
|
||||
pub mutable: Option<Mutable>,
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub _type: Option<Type<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Variable<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(ref _mutable) = self.mutable {
|
||||
write!(f, "mut ")?;
|
||||
}
|
||||
|
||||
write!(f, "{}", self.identifier)?;
|
||||
|
||||
if let Some(ref _type) = self._type {
|
||||
write!(f, ": {}", _type)?;
|
||||
}
|
||||
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
18
ast/src/common/visibility.rs
Normal file
18
ast/src/common/visibility.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::visibility))]
|
||||
pub enum Visibility {
|
||||
Public(Public),
|
||||
Private(Private),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::visibility_public))]
|
||||
pub struct Public {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::visibility_private))]
|
||||
pub struct Private {}
|
5
ast/src/errors/mod.rs
Normal file
5
ast/src/errors/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub mod parser;
|
||||
pub use parser::*;
|
||||
|
||||
pub mod syntax;
|
||||
pub use syntax::*;
|
22
ast/src/errors/parser.rs
Normal file
22
ast/src/errors/parser.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{ast::Rule, errors::SyntaxError};
|
||||
|
||||
use pest::error::Error;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ParserError {
|
||||
#[error("Cannot read from the provided file path - {:?}", _0)]
|
||||
FileReadError(PathBuf),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SyntaxError(#[from] SyntaxError),
|
||||
|
||||
#[error("Unable to construct abstract syntax tree")]
|
||||
SyntaxTreeError,
|
||||
}
|
||||
|
||||
impl From<Error<Rule>> for ParserError {
|
||||
fn from(error: Error<Rule>) -> Self {
|
||||
ParserError::SyntaxError(SyntaxError::from(error))
|
||||
}
|
||||
}
|
44
ast/src/errors/syntax.rs
Normal file
44
ast/src/errors/syntax.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest::error::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SyntaxError {
|
||||
#[error("aborting due to syntax error")]
|
||||
Error,
|
||||
}
|
||||
|
||||
impl From<Error<Rule>> for SyntaxError {
|
||||
fn from(mut error: Error<Rule>) -> Self {
|
||||
error = error.renamed_rules(|rule| match *rule {
|
||||
Rule::LINE_END => "`;`".to_owned(),
|
||||
Rule::type_integer => "`u32`".to_owned(),
|
||||
Rule::type_field => "`field`".to_owned(),
|
||||
Rule::type_group => "`group`".to_owned(),
|
||||
Rule::file => "an import, circuit, or function".to_owned(),
|
||||
Rule::identifier => "a variable name".to_owned(),
|
||||
Rule::type_ => "a type".to_owned(),
|
||||
Rule::access => "`.`, `::`, `()`".to_owned(),
|
||||
|
||||
Rule::operation_and => "`&&`".to_owned(),
|
||||
Rule::operation_or => "`||`".to_owned(),
|
||||
Rule::operation_eq => "`==`".to_owned(),
|
||||
Rule::operation_ne => "`!=`".to_owned(),
|
||||
Rule::operation_ge => "`>=`".to_owned(),
|
||||
Rule::operation_gt => "`>`".to_owned(),
|
||||
Rule::operation_le => "`<=`".to_owned(),
|
||||
Rule::operation_lt => "`<`".to_owned(),
|
||||
Rule::operation_add => "`+`".to_owned(),
|
||||
Rule::operation_sub => "`-`".to_owned(),
|
||||
Rule::operation_mul => "`*`".to_owned(),
|
||||
Rule::operation_div => "`/`".to_owned(),
|
||||
Rule::operation_pow => "`**`".to_owned(),
|
||||
|
||||
rule => format!("{:?}", rule),
|
||||
});
|
||||
|
||||
log::error!("{}\n", error);
|
||||
|
||||
SyntaxError::Error
|
||||
}
|
||||
}
|
13
ast/src/expressions/array_initializer_expression.rs
Normal file
13
ast/src/expressions/array_initializer_expression.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, common::SpreadOrExpression, values::Value};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::expression_array_initializer))]
|
||||
pub struct ArrayInitializerExpression<'ast> {
|
||||
pub expression: Box<SpreadOrExpression<'ast>>,
|
||||
pub count: Value<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
12
ast/src/expressions/array_inline_expression.rs
Normal file
12
ast/src/expressions/array_inline_expression.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, common::SpreadOrExpression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::expression_array_inline))]
|
||||
pub struct ArrayInlineExpression<'ast> {
|
||||
pub expressions: Vec<SpreadOrExpression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
11
ast/src/expressions/binary_expression.rs
Normal file
11
ast/src/expressions/binary_expression.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::{expressions::Expression, operations::BinaryOperation};
|
||||
|
||||
use pest::Span;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct BinaryExpression<'ast> {
|
||||
pub operation: BinaryOperation,
|
||||
pub left: Box<Expression<'ast>>,
|
||||
pub right: Box<Expression<'ast>>,
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/expressions/circuit_inline_expression.rs
Normal file
13
ast/src/expressions/circuit_inline_expression.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, circuits::CircuitField, common::Identifier,};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::expression_circuit_inline))]
|
||||
pub struct CircuitInlineExpression<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub members: Vec<CircuitField<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
99
ast/src/expressions/expression.rs
Normal file
99
ast/src/expressions/expression.rs
Normal file
@ -0,0 +1,99 @@
|
||||
use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value,};
|
||||
|
||||
use pest::Span;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Expression<'ast> {
|
||||
Value(Value<'ast>),
|
||||
Identifier(Identifier<'ast>),
|
||||
Not(NotExpression<'ast>),
|
||||
Binary(BinaryExpression<'ast>),
|
||||
Ternary(TernaryExpression<'ast>),
|
||||
ArrayInline(ArrayInlineExpression<'ast>),
|
||||
ArrayInitializer(ArrayInitializerExpression<'ast>),
|
||||
CircuitInline(CircuitInlineExpression<'ast>),
|
||||
Postfix(PostfixExpression<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> Expression<'ast> {
|
||||
pub fn binary(
|
||||
operation: BinaryOperation,
|
||||
left: Box<Expression<'ast>>,
|
||||
right: Box<Expression<'ast>>,
|
||||
span: Span<'ast>,
|
||||
) -> Self {
|
||||
Expression::Binary(BinaryExpression {
|
||||
operation,
|
||||
left,
|
||||
right,
|
||||
span,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ternary(
|
||||
first: Box<Expression<'ast>>,
|
||||
second: Box<Expression<'ast>>,
|
||||
third: Box<Expression<'ast>>,
|
||||
span: Span<'ast>,
|
||||
) -> Self {
|
||||
Expression::Ternary(TernaryExpression {
|
||||
first,
|
||||
second,
|
||||
third,
|
||||
span,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn span(&self) -> &Span<'ast> {
|
||||
match self {
|
||||
Expression::Value(expression) => &expression.span(),
|
||||
Expression::Identifier(expression) => &expression.span,
|
||||
Expression::Not(expression) => &expression.span,
|
||||
Expression::Binary(expression) => &expression.span,
|
||||
Expression::Ternary(expression) => &expression.span,
|
||||
Expression::ArrayInline(expression) => &expression.span,
|
||||
Expression::ArrayInitializer(expression) => &expression.span,
|
||||
Expression::CircuitInline(expression) => &expression.span,
|
||||
Expression::Postfix(expression) => &expression.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Expression<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Expression::Value(ref expression) => write!(f, "{}", expression),
|
||||
Expression::Identifier(ref expression) => write!(f, "{}", expression),
|
||||
Expression::Not(ref expression) => write!(f, "!{}", expression.expression),
|
||||
Expression::Binary(ref expression) => {
|
||||
write!(f, "{} == {}", expression.left, expression.right)
|
||||
}
|
||||
Expression::Ternary(ref expression) => write!(
|
||||
f,
|
||||
"if {} ? {} : {}",
|
||||
expression.first, expression.second, expression.third
|
||||
),
|
||||
Expression::ArrayInline(ref expression) => {
|
||||
for (i, spread_or_expression) in expression.expressions.iter().enumerate() {
|
||||
write!(f, "{}", spread_or_expression)?;
|
||||
if i < expression.expressions.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "")
|
||||
}
|
||||
Expression::ArrayInitializer(ref expression) => {
|
||||
write!(f, "[{} ; {}]", expression.expression, expression.count)
|
||||
}
|
||||
Expression::CircuitInline(ref expression) => write!(
|
||||
f,
|
||||
"inline circuit display not impl {}",
|
||||
expression.identifier
|
||||
),
|
||||
Expression::Postfix(ref expression) => {
|
||||
write!(f, "Postfix display not impl {}", expression.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
ast/src/expressions/mod.rs
Normal file
23
ast/src/expressions/mod.rs
Normal file
@ -0,0 +1,23 @@
|
||||
pub mod array_initializer_expression;
|
||||
pub use array_initializer_expression::*;
|
||||
|
||||
pub mod array_inline_expression;
|
||||
pub use array_inline_expression::*;
|
||||
|
||||
pub mod binary_expression;
|
||||
pub use binary_expression::*;
|
||||
|
||||
pub mod circuit_inline_expression;
|
||||
pub use circuit_inline_expression::*;
|
||||
|
||||
pub mod expression;
|
||||
pub use expression::*;
|
||||
|
||||
pub mod not_expression;
|
||||
pub use not_expression::*;
|
||||
|
||||
pub mod postfix_expression;
|
||||
pub use postfix_expression::*;
|
||||
|
||||
pub mod ternary_expression;
|
||||
pub use ternary_expression::*;
|
13
ast/src/expressions/not_expression.rs
Normal file
13
ast/src/expressions/not_expression.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, expressions::Expression, operations::NotOperation};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::expression_not))]
|
||||
pub struct NotExpression<'ast> {
|
||||
pub operation: NotOperation<'ast>,
|
||||
pub expression: Box<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/expressions/postfix_expression.rs
Normal file
13
ast/src/expressions/postfix_expression.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{access::Access, ast::Rule, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::expression_postfix))]
|
||||
pub struct PostfixExpression<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub accesses: Vec<Access<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
14
ast/src/expressions/ternary_expression.rs
Normal file
14
ast/src/expressions/ternary_expression.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use crate::{ast::Rule, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::expression_conditional))]
|
||||
pub struct TernaryExpression<'ast> {
|
||||
pub first: Box<Expression<'ast>>,
|
||||
pub second: Box<Expression<'ast>>,
|
||||
pub third: Box<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
16
ast/src/files/file.rs
Normal file
16
ast/src/files/file.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use crate::{ast::Rule, common::EOI, functions::{Function, TestFunction}, imports::Import, circuits::Circuit};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::file))]
|
||||
pub struct File<'ast> {
|
||||
pub imports: Vec<Import<'ast>>,
|
||||
pub circuits: Vec<Circuit<'ast>>,
|
||||
pub functions: Vec<Function<'ast>>,
|
||||
pub tests: Vec<TestFunction<'ast>>,
|
||||
pub eoi: EOI,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
2
ast/src/files/mod.rs
Normal file
2
ast/src/files/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod file;
|
||||
pub use file::*;
|
15
ast/src/functions/function.rs
Normal file
15
ast/src/functions/function.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::{ast::Rule, common::Identifier, functions::FunctionInput, statements::Statement, types::Type};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::function_definition))]
|
||||
pub struct Function<'ast> {
|
||||
pub function_name: Identifier<'ast>,
|
||||
pub parameters: Vec<FunctionInput<'ast>>,
|
||||
pub returns: Vec<Type<'ast>>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
15
ast/src/functions/function_input.rs
Normal file
15
ast/src/functions/function_input.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::{ast::Rule, common::{Identifier, Visibility, Mutable}, types::Type};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::function_input))]
|
||||
pub struct FunctionInput<'ast> {
|
||||
pub mutable: Option<Mutable>,
|
||||
pub identifier: Identifier<'ast>,
|
||||
pub visibility: Option<Visibility>,
|
||||
pub _type: Type<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
8
ast/src/functions/mod.rs
Normal file
8
ast/src/functions/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
pub mod function;
|
||||
pub use function::*;
|
||||
|
||||
pub mod function_input;
|
||||
pub use function_input::*;
|
||||
|
||||
pub mod test_function;
|
||||
pub use test_function::*;
|
12
ast/src/functions/test_function.rs
Normal file
12
ast/src/functions/test_function.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, functions::Function};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::test_function))]
|
||||
pub struct TestFunction<'ast> {
|
||||
pub function: Function<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
14
ast/src/imports/import.rs
Normal file
14
ast/src/imports/import.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use crate::{ast::Rule, common::LineEnd, imports::{ImportSource, ImportSymbol}};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::import))]
|
||||
pub struct Import<'ast> {
|
||||
pub source: ImportSource<'ast>,
|
||||
pub symbols: Vec<ImportSymbol<'ast>>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/imports/import_source.rs
Normal file
13
ast/src/imports/import_source.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::ast::{Rule, span_into_string};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::import_source))]
|
||||
pub struct ImportSource<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
13
ast/src/imports/import_symbol.rs
Normal file
13
ast/src/imports/import_symbol.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::import_symbol))]
|
||||
pub struct ImportSymbol<'ast> {
|
||||
pub value: Identifier<'ast>,
|
||||
pub alias: Option<Identifier<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
8
ast/src/imports/mod.rs
Normal file
8
ast/src/imports/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
pub mod import;
|
||||
pub use import::*;
|
||||
|
||||
pub mod import_source;
|
||||
pub use import_source::*;
|
||||
|
||||
pub mod import_symbol;
|
||||
pub use import_symbol::*;
|
299
ast/src/leo.pest
Normal file
299
ast/src/leo.pest
Normal file
@ -0,0 +1,299 @@
|
||||
/// Common
|
||||
|
||||
// Declared in common/assignee.rs
|
||||
assignee = { identifier ~ access_assignee* }
|
||||
|
||||
// Declared in common/file.rs
|
||||
file = { SOI ~ NEWLINE* ~ import* ~ NEWLINE* ~ circuit_definition* ~ NEWLINE* ~ function_definition* ~ NEWLINE* ~ test_function* ~ NEWLINE* ~ EOI }
|
||||
|
||||
// Declared in common/identifier.rs
|
||||
identifier = @{ ((!protected_name ~ ASCII_ALPHA) | (protected_name ~ (ASCII_ALPHANUMERIC | "_"))) ~ (ASCII_ALPHANUMERIC | "_")* }
|
||||
protected_name = { visibility | "let" | "for"| "if" | "else" | "as" | "return" }
|
||||
|
||||
// Declared in common/line_end.rs
|
||||
LINE_END = { ";" ~ NEWLINE* }
|
||||
|
||||
// Declared in common/mutable.rs
|
||||
mutable = { "mut" }
|
||||
|
||||
// Declared in common/range.rs
|
||||
range = { from_expression? ~ ".." ~ to_expression }
|
||||
from_expression = { expression }
|
||||
to_expression = { expression }
|
||||
|
||||
// Declared in common/range_or_expression.rs
|
||||
range_or_expression = { range | expression }
|
||||
|
||||
// Declared in common/spread.rs
|
||||
spread = { "..." ~ expression }
|
||||
|
||||
// Declared in common/spread_or_expression.rs
|
||||
spread_or_expression = { spread | expression }
|
||||
|
||||
// Declared in common/static_.rs
|
||||
static_ = { "static" }
|
||||
|
||||
// Declared in common/variable.rs
|
||||
variable = { mutable? ~ identifier ~ (":" ~ type_)? }
|
||||
|
||||
// Declared in common/visibility.rs
|
||||
visibility = { visibility_public | visibility_private }
|
||||
visibility_public = { "public" }
|
||||
visibility_private = { "private" }
|
||||
|
||||
/// Operations
|
||||
|
||||
// Declared in operations/not_operation.rs
|
||||
operation_not = { "!" }
|
||||
|
||||
// Declared in operations/binary_operation.rs
|
||||
operation_and = { "&&" }
|
||||
operation_or = { "||" }
|
||||
operation_eq = { "==" }
|
||||
operation_ne = { "!=" }
|
||||
operation_ge = { ">=" }
|
||||
operation_gt = { ">" }
|
||||
operation_le = { "<=" }
|
||||
operation_lt = { "<" }
|
||||
operation_add = { "+" }
|
||||
operation_sub = { "-" }
|
||||
operation_mul = { "*" }
|
||||
operation_div = { "/" }
|
||||
operation_pow = { "**" }
|
||||
|
||||
operation_compare = _{
|
||||
operation_eq | operation_ne |
|
||||
operation_ge | operation_gt |
|
||||
operation_le | operation_lt
|
||||
}
|
||||
operation_binary = _{
|
||||
operation_compare | operation_and | operation_or |
|
||||
operation_add | operation_sub | operation_pow | operation_mul | operation_div
|
||||
}
|
||||
|
||||
// Declared in operations/assign_operation.rs
|
||||
operation_assign = {
|
||||
assign | operation_add_assign | operation_sub_assign |
|
||||
operation_mul_assign | operation_div_assign | operation_pow_assign
|
||||
}
|
||||
assign = { "=" }
|
||||
operation_add_assign = { "+=" }
|
||||
operation_sub_assign = { "-=" }
|
||||
operation_mul_assign = { "*=" }
|
||||
operation_div_assign = { "/=" }
|
||||
operation_pow_assign = { "**=" }
|
||||
|
||||
/// Types
|
||||
|
||||
// Declared in types/type_.rs
|
||||
type_ = { type_self | type_array | type_data | type_circuit }
|
||||
|
||||
// Declared in types/integer.rs
|
||||
type_integer = {
|
||||
type_u8
|
||||
| type_u16
|
||||
| type_u32
|
||||
| type_u64
|
||||
| type_u128
|
||||
}
|
||||
type_u8 = { "u8" }
|
||||
type_u16 = { "u16" }
|
||||
type_u32 = { "u32" }
|
||||
type_u64 = { "u64" }
|
||||
type_u128 = { "u128" }
|
||||
|
||||
// Declared in types/field_type.rs
|
||||
type_field = { "field" }
|
||||
|
||||
// Declared in types/group_type.rs
|
||||
type_group = { "group" }
|
||||
|
||||
// Declared in types/boolean_type.rs
|
||||
type_boolean = { "bool" }
|
||||
|
||||
// Declared in types/data_type.rs
|
||||
type_data = { type_field | type_group | type_boolean | type_integer }
|
||||
|
||||
// Declared in types/self_type.rs
|
||||
type_self = { "Self" }
|
||||
|
||||
// Declared in types/self_type.rs
|
||||
type_circuit = { identifier }
|
||||
|
||||
// Declared in types/array_type.rs
|
||||
type_array = { type_data ~ ("[" ~ value ~ "]")+ }
|
||||
|
||||
type_list = _{ (type_ ~ ("," ~ type_)*)? }
|
||||
|
||||
/// Values
|
||||
|
||||
// Declared in values/value.rs
|
||||
value = { value_field | value_group | value_boolean | value_integer | value_implicit }
|
||||
|
||||
// Declared in values/number_value.rs
|
||||
value_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
|
||||
|
||||
// Declared in values/number_implicit_value.rs
|
||||
value_implicit = { value_number }
|
||||
|
||||
// Declared in values/integer_value.rs
|
||||
value_integer = { value_number ~ type_integer }
|
||||
|
||||
// Declared in values/boolean_value.rs
|
||||
value_boolean = { "true" | "false" }
|
||||
|
||||
// Declared in values/field_value.rs
|
||||
value_field = { value_number ~ type_field }
|
||||
|
||||
// Declared in values/group_value.rs
|
||||
value_group = { group_single_or_tuple ~ type_group }
|
||||
group_tuple = {"(" ~ value_number ~ "," ~ value_number ~ ")"}
|
||||
group_single_or_tuple = {value_number | group_tuple}
|
||||
|
||||
/// Access
|
||||
|
||||
// Declared in access/access.rs
|
||||
access = { access_array | access_call | access_member | access_static_member}
|
||||
|
||||
// Declared in access/array_access.rs
|
||||
access_array = { "[" ~ range_or_expression ~ "]" }
|
||||
|
||||
// Declared in access/assignee_access.rs
|
||||
access_assignee = { access_array | access_member }
|
||||
|
||||
// Declared in access/call_access.rs
|
||||
access_call = { "(" ~ expression_tuple ~ ")" }
|
||||
|
||||
// Declared in access/member_access.rs
|
||||
access_member = { "." ~ identifier }
|
||||
|
||||
// Declared in access/static_member_access.rs
|
||||
access_static_member = { "::" ~ identifier }
|
||||
|
||||
/// Circuits
|
||||
|
||||
// Declared in circuits/circuit_definition.rs
|
||||
circuit_definition = { "circuit" ~ identifier ~ "{" ~ NEWLINE* ~ circuit_member* ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
||||
|
||||
// Declared in circuits/circuit_field.rs
|
||||
circuit_field = { identifier ~ ":" ~ expression }
|
||||
|
||||
// Declared in circuits/circuit_field_definition.rs
|
||||
circuit_field_definition = { identifier ~ ":" ~ type_ ~ NEWLINE* }
|
||||
|
||||
// Declared in circuits/circuit_function.rs
|
||||
circuit_function = { static_? ~ function_definition }
|
||||
|
||||
// Declared in circuits/circuit_member.rs
|
||||
circuit_member = { circuit_function | circuit_field_definition }
|
||||
|
||||
/// Conditionals
|
||||
|
||||
expression_conditional = { "if" ~ expression ~ "?" ~ expression ~ ":" ~ expression}
|
||||
|
||||
/// Expressions
|
||||
|
||||
expression_term = {
|
||||
("(" ~ expression ~ ")")
|
||||
| expression_array_initializer
|
||||
| expression_array_inline
|
||||
| expression_circuit_inline
|
||||
| expression_conditional
|
||||
| expression_not
|
||||
| expression_postfix
|
||||
| expression_primitive
|
||||
}
|
||||
expression_primitive = { value | identifier }
|
||||
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
|
||||
|
||||
// Declared in expressions/expression.rs
|
||||
expression = { expression_term ~ (operation_binary ~ expression_term)* }
|
||||
|
||||
// Declared in expressions/array_initializer_expression.rs
|
||||
expression_array_initializer = { "[" ~ spread_or_expression ~ ";" ~ value ~ "]" }
|
||||
|
||||
// Declared in expressions/array_inline_expression.rs
|
||||
expression_array_inline = { "[" ~ NEWLINE* ~ inline_array_inner ~ NEWLINE* ~ "]"}
|
||||
inline_array_inner = _{(spread_or_expression ~ ("," ~ NEWLINE* ~ spread_or_expression)*)?}
|
||||
|
||||
// Declared in expressions/circuit_inline_expression.rs
|
||||
expression_circuit_inline = { identifier ~ "{" ~ NEWLINE* ~ circuit_field_list ~ NEWLINE* ~ "}" }
|
||||
circuit_field_list = _{ (circuit_field ~ ("," ~ NEWLINE* ~ circuit_field)*)? ~ ","? }
|
||||
|
||||
// Declared in expressions/not_expression.rs
|
||||
expression_not = { operation_not ~ expression_term }
|
||||
|
||||
// Declared in expressions/postfix_expression.rs
|
||||
expression_postfix = { identifier ~ access+ }
|
||||
|
||||
/// Statements
|
||||
|
||||
// Declared in statements/statement.rs
|
||||
statement = {
|
||||
(statement_return
|
||||
| statement_conditional
|
||||
| statement_for
|
||||
| (statement_multiple_assignment
|
||||
| statement_assert
|
||||
| statement_definition
|
||||
| statement_assign
|
||||
| statement_expression
|
||||
)
|
||||
) ~ NEWLINE*
|
||||
}
|
||||
|
||||
// Declared in statements/assert_statement.rs
|
||||
statement_assert = { assert_eq }
|
||||
assert_eq = {"assert_eq!" ~ "(" ~ NEWLINE* ~ expression ~ "," ~ NEWLINE* ~ expression ~ NEWLINE* ~ ")" ~ LINE_END}
|
||||
|
||||
// Declared in statements/assign_statement.rs
|
||||
statement_assign = { assignee ~ operation_assign ~ expression ~ LINE_END }
|
||||
|
||||
// Declared in statements/conditional_statement.rs
|
||||
statement_conditional = {"if" ~ (expression | "(" ~ expression ~ ")") ~ "{" ~ NEWLINE* ~ statement+ ~ "}" ~ ("else" ~ conditional_nested_or_end_statement)?}
|
||||
conditional_nested_or_end_statement = { statement_conditional | "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
|
||||
// Declared in statements/definition_statement.rs
|
||||
statement_definition = { "let" ~ variable ~ "=" ~ expression ~ LINE_END}
|
||||
|
||||
// Declared in statements/expression_statement.rs
|
||||
statement_expression = { expression ~ LINE_END }
|
||||
|
||||
// Declared in statements/for_statement.rs
|
||||
statement_for = { "for" ~ identifier ~ "in" ~ expression ~ ".." ~ expression ~ "{" ~ NEWLINE* ~ statement+ ~ "}"}
|
||||
|
||||
// Declared in statements/multiple_assignment_statement.rs
|
||||
statement_multiple_assignment = { "let" ~ "(" ~ variable_tuple ~ ")" ~ "=" ~ identifier ~ "(" ~ expression_tuple ~ ")" ~ LINE_END}
|
||||
variable_tuple = _{ variable ~ ("," ~ variable)* }
|
||||
|
||||
// Declared in statements/return_statement.rs
|
||||
statement_return = { "return" ~ expression_tuple }
|
||||
|
||||
/// Functions
|
||||
|
||||
// Declared in functions/function.rs
|
||||
function_definition = { "function" ~ identifier ~ "(" ~ input_model_list ~ ")" ~ ("->" ~ (type_ | "(" ~ type_list ~ ")"))? ~ "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" ~ NEWLINE* }
|
||||
|
||||
// Declared in functions/function_input.rs
|
||||
function_input = { mutable? ~ identifier ~ ":" ~ visibility? ~ type_ }
|
||||
input_model_list = _{ (function_input ~ ("," ~ function_input)*)? }
|
||||
|
||||
// Declared in functions/test_function.rs
|
||||
test_function = { "test" ~ function_definition }
|
||||
|
||||
/// Imports
|
||||
|
||||
// Declared in imports/import.rs
|
||||
import = { "from" ~ "\"" ~ import_source ~ "\"" ~ "import" ~ ("*" | ("{" ~ NEWLINE* ~ import_symbol_tuple ~ NEWLINE* ~ "}") | import_symbol) ~ LINE_END}
|
||||
|
||||
// Declared in imports/import_source.rs
|
||||
import_source = @{ (!"\"" ~ ANY)* }
|
||||
|
||||
// Declared in imports/import_symbol.rs
|
||||
import_symbol = { identifier ~ ("as" ~ identifier)? }
|
||||
import_symbol_tuple = _{ import_symbol ~ ("," ~ NEWLINE* ~ import_symbol)* }
|
||||
|
||||
/// Utilities
|
||||
|
||||
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
||||
WHITESPACE = _{ " " | "\t" ~ (NEWLINE)* }
|
48
ast/src/lib.rs
Normal file
48
ast/src/lib.rs
Normal file
@ -0,0 +1,48 @@
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
pub mod errors;
|
||||
pub use errors::*;
|
||||
|
||||
pub mod access;
|
||||
mod ast;
|
||||
pub mod circuits;
|
||||
pub mod common;
|
||||
pub mod expressions;
|
||||
pub mod files;
|
||||
pub mod functions;
|
||||
pub mod imports;
|
||||
pub mod operations;
|
||||
pub mod statements;
|
||||
pub mod values;
|
||||
pub mod types;
|
||||
|
||||
use from_pest::FromPest;
|
||||
use std::{path::PathBuf, fs};
|
||||
|
||||
pub struct LeoParser;
|
||||
|
||||
impl LeoParser {
|
||||
/// Reads in the given file path into a string.
|
||||
pub fn load_file(file_path: &PathBuf) -> Result<String, ParserError> {
|
||||
Ok(fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.clone()))?)
|
||||
}
|
||||
|
||||
/// Parses the input file and constructs a syntax tree.
|
||||
pub fn parse_file<'a>(file_path: &'a PathBuf, input_file: &'a str) -> Result<files::File<'a>, ParserError> {
|
||||
// Parse the file using leo.pest
|
||||
let mut file = ast::parse(input_file).map_err(|error| {
|
||||
ParserError::from(error.with_path(file_path.to_str().unwrap()))
|
||||
})?;
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree = files::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?;
|
||||
log::debug!("{:#?}", syntax_tree);
|
||||
|
||||
Ok(syntax_tree)
|
||||
}
|
||||
}
|
38
ast/src/operations/assign_operation.rs
Normal file
38
ast/src/operations/assign_operation.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_assign))]
|
||||
pub enum AssignOperation {
|
||||
Assign(Assign),
|
||||
AddAssign(AddAssign),
|
||||
SubAssign(SubAssign),
|
||||
MulAssign(MulAssign),
|
||||
DivAssign(DivAssign),
|
||||
PowAssign(PowAssign),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::assign))]
|
||||
pub struct Assign {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_add_assign))]
|
||||
pub struct AddAssign {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_sub_assign))]
|
||||
pub struct SubAssign {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_mul_assign))]
|
||||
pub struct MulAssign {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_div_assign))]
|
||||
pub struct DivAssign {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_pow_assign))]
|
||||
pub struct PowAssign {}
|
21
ast/src/operations/binary_operation.rs
Normal file
21
ast/src/operations/binary_operation.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_binary))]
|
||||
pub enum BinaryOperation {
|
||||
Or,
|
||||
And,
|
||||
Eq,
|
||||
Ne,
|
||||
Ge,
|
||||
Gt,
|
||||
Le,
|
||||
Lt,
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Pow,
|
||||
}
|
8
ast/src/operations/mod.rs
Normal file
8
ast/src/operations/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
pub mod assign_operation;
|
||||
pub use assign_operation::*;
|
||||
|
||||
pub mod binary_operation;
|
||||
pub use binary_operation::*;
|
||||
|
||||
pub mod not_operation;
|
||||
pub use not_operation::*;
|
11
ast/src/operations/not_operation.rs
Normal file
11
ast/src/operations/not_operation.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::operation_not))]
|
||||
pub struct NotOperation<'ast> {
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
31
ast/src/statements/assert_statement.rs
Normal file
31
ast/src/statements/assert_statement.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use crate::{ast::Rule, common::LineEnd, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_assert))]
|
||||
pub enum AssertStatement<'ast> {
|
||||
AssertEq(AssertEq<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for AssertStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
AssertStatement::AssertEq(ref assert) => {
|
||||
write!(f, "assert_eq({}, {});", assert.left, assert.right)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::assert_eq))]
|
||||
pub struct AssertEq<'ast> {
|
||||
pub left: Expression<'ast>,
|
||||
pub right: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
22
ast/src/statements/assign_statement.rs
Normal file
22
ast/src/statements/assign_statement.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{ast::Rule, common::{Assignee, LineEnd}, expressions::Expression, operations::AssignOperation};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_assign))]
|
||||
pub struct AssignStatement<'ast> {
|
||||
pub assignee: Assignee<'ast>,
|
||||
pub assign: AssignOperation,
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for AssignStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} = {};", self.assignee, self.expression)
|
||||
}
|
||||
}
|
22
ast/src/statements/conditional_nested_or_end_statement.rs
Normal file
22
ast/src/statements/conditional_nested_or_end_statement.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{ast::Rule, statements::{ConditionalStatement, Statement}};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::conditional_nested_or_end_statement))]
|
||||
pub enum ConditionalNestedOrEndStatement<'ast> {
|
||||
Nested(Box<ConditionalStatement<'ast>>),
|
||||
End(Vec<Statement<'ast>>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalNestedOrEndStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
|
||||
ConditionalNestedOrEndStatement::End(ref statements) => {
|
||||
write!(f, "else {{\n \t{:#?}\n }}", statements)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
ast/src/statements/conditional_statement.rs
Normal file
26
ast/src/statements/conditional_statement.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::{ast::Rule, expressions::Expression, statements::{ConditionalNestedOrEndStatement, Statement}};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_conditional))]
|
||||
pub struct ConditionalStatement<'ast> {
|
||||
pub condition: Expression<'ast>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
pub next: Option<ConditionalNestedOrEndStatement<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ConditionalStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "if ({}) {{\n", self.condition)?;
|
||||
write!(f, "\t{:#?}\n", self.statements)?;
|
||||
self.next
|
||||
.as_ref()
|
||||
.map(|n_or_e| write!(f, "}} {}", n_or_e))
|
||||
.unwrap_or(write!(f, "}}"))
|
||||
}
|
||||
}
|
21
ast/src/statements/definition_statement.rs
Normal file
21
ast/src/statements/definition_statement.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::{ast::Rule, common::{LineEnd, Variable}, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_definition))]
|
||||
pub struct DefinitionStatement<'ast> {
|
||||
pub variable: Variable<'ast>,
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for DefinitionStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "let {} = {};", self.variable, self.expression)
|
||||
}
|
||||
}
|
13
ast/src/statements/expression_statement.rs
Normal file
13
ast/src/statements/expression_statement.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, common::LineEnd, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_expression))]
|
||||
pub struct ExpressionStatement<'ast> {
|
||||
pub expression: Expression<'ast>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
26
ast/src/statements/for_statement.rs
Normal file
26
ast/src/statements/for_statement.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::{ast::Rule, expressions::{Expression}, statements::Statement, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_for))]
|
||||
pub struct ForStatement<'ast> {
|
||||
pub index: Identifier<'ast>,
|
||||
pub start: Expression<'ast>,
|
||||
pub stop: Expression<'ast>,
|
||||
pub statements: Vec<Statement<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ForStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"for {} in {}..{} {{ {:#?} }}",
|
||||
self.index, self.start, self.stop, self.statements
|
||||
)
|
||||
}
|
||||
}
|
29
ast/src/statements/mod.rs
Normal file
29
ast/src/statements/mod.rs
Normal file
@ -0,0 +1,29 @@
|
||||
pub mod assert_statement;
|
||||
pub use assert_statement::*;
|
||||
|
||||
pub mod assign_statement;
|
||||
pub use assign_statement::*;
|
||||
|
||||
pub mod conditional_statement;
|
||||
pub use conditional_statement::*;
|
||||
|
||||
pub mod conditional_nested_or_end_statement;
|
||||
pub use conditional_nested_or_end_statement::*;
|
||||
|
||||
pub mod definition_statement;
|
||||
pub use definition_statement::*;
|
||||
|
||||
pub mod expression_statement;
|
||||
pub use expression_statement::*;
|
||||
|
||||
pub mod for_statement;
|
||||
pub use for_statement::*;
|
||||
|
||||
pub mod multiple_assignment_statement;
|
||||
pub use multiple_assignment_statement::*;
|
||||
|
||||
pub mod return_statement;
|
||||
pub use return_statement::*;
|
||||
|
||||
pub mod statement;
|
||||
pub use statement::*;
|
28
ast/src/statements/multiple_assignment_statement.rs
Normal file
28
ast/src/statements/multiple_assignment_statement.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::{ast::Rule, common::{Identifier, LineEnd, Variable}, expressions::{Expression}};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_multiple_assignment))]
|
||||
pub struct MultipleAssignmentStatement<'ast> {
|
||||
pub variables: Vec<Variable<'ast>>,
|
||||
pub function_name: Identifier<'ast>,
|
||||
pub arguments: Vec<Expression<'ast>>,
|
||||
pub line_end: LineEnd,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for MultipleAssignmentStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, id) in self.variables.iter().enumerate() {
|
||||
write!(f, "{}", id)?;
|
||||
if i < self.variables.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, " = {}", self.function_name)
|
||||
}
|
||||
}
|
25
ast/src/statements/return_statement.rs
Normal file
25
ast/src/statements/return_statement.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::{ast::Rule, expressions::Expression};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement_return))]
|
||||
pub struct ReturnStatement<'ast> {
|
||||
pub expressions: Vec<Expression<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for ReturnStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, expression) in self.expressions.iter().enumerate() {
|
||||
write!(f, "{}", expression)?;
|
||||
if i < self.expressions.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
32
ast/src/statements/statement.rs
Normal file
32
ast/src/statements/statement.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use crate::{ast::Rule, statements::*};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::statement))]
|
||||
pub enum Statement<'ast> {
|
||||
Return(ReturnStatement<'ast>),
|
||||
Definition(DefinitionStatement<'ast>),
|
||||
Assign(AssignStatement<'ast>),
|
||||
MultipleAssignment(MultipleAssignmentStatement<'ast>),
|
||||
Conditional(ConditionalStatement<'ast>),
|
||||
Iteration(ForStatement<'ast>),
|
||||
Assert(AssertStatement<'ast>),
|
||||
Expression(ExpressionStatement<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Statement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Return(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Definition(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Assign(ref statement) => write!(f, "{}", statement),
|
||||
Statement::MultipleAssignment(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Conditional(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Iteration(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Assert(ref statement) => write!(f, "{}", statement),
|
||||
Statement::Expression(ref statement) => write!(f, "{}", statement.expression),
|
||||
}
|
||||
}
|
||||
}
|
13
ast/src/types/array_type.rs
Normal file
13
ast/src/types/array_type.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::{ast::Rule, types::DataType, values::Value};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_array))]
|
||||
pub struct ArrayType<'ast> {
|
||||
pub _type: DataType,
|
||||
pub dimensions: Vec<Value<'ast>>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
7
ast/src/types/boolean_type.rs
Normal file
7
ast/src/types/boolean_type.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_boolean))]
|
||||
pub struct BooleanType {}
|
12
ast/src/types/circuit_type.rs
Normal file
12
ast/src/types/circuit_type.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_circuit))]
|
||||
pub struct CircuitType<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
12
ast/src/types/data_type.rs
Normal file
12
ast/src/types/data_type.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{ast::Rule, types::{IntegerType, FieldType, GroupType, BooleanType}};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_data))]
|
||||
pub enum DataType {
|
||||
Integer(IntegerType),
|
||||
Field(FieldType),
|
||||
Group(GroupType),
|
||||
Boolean(BooleanType),
|
||||
}
|
7
ast/src/types/field_type.rs
Normal file
7
ast/src/types/field_type.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_field))]
|
||||
pub struct FieldType {}
|
7
ast/src/types/group_type.rs
Normal file
7
ast/src/types/group_type.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_group))]
|
||||
pub struct GroupType {}
|
33
ast/src/types/integer_type.rs
Normal file
33
ast/src/types/integer_type.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_integer))]
|
||||
pub enum IntegerType {
|
||||
U8Type(U8Type),
|
||||
U16Type(U16Type),
|
||||
U32Type(U32Type),
|
||||
U64Type(U64Type),
|
||||
U128Type(U128Type),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_u8))]
|
||||
pub struct U8Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_u16))]
|
||||
pub struct U16Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_u32))]
|
||||
pub struct U32Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_u64))]
|
||||
pub struct U64Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_u128))]
|
||||
pub struct U128Type {}
|
26
ast/src/types/mod.rs
Normal file
26
ast/src/types/mod.rs
Normal file
@ -0,0 +1,26 @@
|
||||
pub mod array_type;
|
||||
pub use array_type::*;
|
||||
|
||||
pub mod boolean_type;
|
||||
pub use boolean_type::*;
|
||||
|
||||
pub mod circuit_type;
|
||||
pub use circuit_type::*;
|
||||
|
||||
pub mod data_type;
|
||||
pub use data_type::*;
|
||||
|
||||
pub mod field_type;
|
||||
pub use field_type::*;
|
||||
|
||||
pub mod group_type;
|
||||
pub use group_type::*;
|
||||
|
||||
pub mod integer_type;
|
||||
pub use integer_type::*;
|
||||
|
||||
pub mod self_type;
|
||||
pub use self_type::*;
|
||||
|
||||
pub mod type_;
|
||||
pub use type_::*;
|
7
ast/src/types/self_type.rs
Normal file
7
ast/src/types/self_type.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_self))]
|
||||
pub struct SelfType {}
|
24
ast/src/types/type_.rs
Normal file
24
ast/src/types/type_.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::{ast::Rule, types::*};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_))]
|
||||
pub enum Type<'ast> {
|
||||
Basic(DataType),
|
||||
Array(ArrayType<'ast>),
|
||||
Circuit(CircuitType<'ast>),
|
||||
SelfType(SelfType),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Type<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Type::Basic(ref _type) => write!(f, "basic"),
|
||||
Type::Array(ref _type) => write!(f, "array"),
|
||||
Type::Circuit(ref _type) => write!(f, "struct"),
|
||||
Type::SelfType(ref _type) => write!(f, "Self"),
|
||||
}
|
||||
}
|
||||
}
|
20
ast/src/values/boolean_value.rs
Normal file
20
ast/src/values/boolean_value.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::ast::{Rule, span_into_string};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_boolean))]
|
||||
pub struct BooleanValue<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for BooleanValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
20
ast/src/values/field_value.rs
Normal file
20
ast/src/values/field_value.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{ast::Rule, types::FieldType, values::NumberValue,};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_field))]
|
||||
pub struct FieldValue<'ast> {
|
||||
pub number: NumberValue<'ast>,
|
||||
pub _type: FieldType,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for FieldValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.number)
|
||||
}
|
||||
}
|
51
ast/src/values/group_value.rs
Normal file
51
ast/src/values/group_value.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use crate::{ast::Rule, types::GroupType, values::NumberValue,};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_group))]
|
||||
pub struct GroupValue<'ast> {
|
||||
pub value: GroupRepresentation<'ast>,
|
||||
pub _type: GroupType,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for GroupValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::group_single_or_tuple))]
|
||||
pub enum GroupRepresentation<'ast> {
|
||||
Single(NumberValue<'ast>),
|
||||
Tuple(GroupTuple<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for GroupRepresentation<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
GroupRepresentation::Single(number) => write!(f, "{}", number),
|
||||
GroupRepresentation::Tuple(tuple) => write!(f, "{}", tuple),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::group_tuple))]
|
||||
pub struct GroupTuple<'ast> {
|
||||
pub x: NumberValue<'ast>,
|
||||
pub y: NumberValue<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for GroupTuple<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
20
ast/src/values/integer_value.rs
Normal file
20
ast/src/values/integer_value.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{ast::Rule, types::IntegerType, values::NumberValue};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_integer))]
|
||||
pub struct IntegerValue<'ast> {
|
||||
pub number: NumberValue<'ast>,
|
||||
pub _type: IntegerType,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for IntegerValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.number)
|
||||
}
|
||||
}
|
20
ast/src/values/mod.rs
Normal file
20
ast/src/values/mod.rs
Normal file
@ -0,0 +1,20 @@
|
||||
pub mod boolean_value;
|
||||
pub use boolean_value::*;
|
||||
|
||||
pub mod field_value;
|
||||
pub use field_value::*;
|
||||
|
||||
pub mod group_value;
|
||||
pub use group_value::*;
|
||||
|
||||
pub mod integer_value;
|
||||
pub use integer_value::*;
|
||||
|
||||
pub mod number_implicit_value;
|
||||
pub use number_implicit_value::*;
|
||||
|
||||
pub mod number_value;
|
||||
pub use number_value::*;
|
||||
|
||||
pub mod value;
|
||||
pub use value::*;
|
19
ast/src/values/number_implicit_value.rs
Normal file
19
ast/src/values/number_implicit_value.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use crate::{ast::Rule, values::NumberValue};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_implicit))]
|
||||
pub struct NumberImplicitValue<'ast> {
|
||||
pub number: NumberValue<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for NumberImplicitValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.number)
|
||||
}
|
||||
}
|
20
ast/src/values/number_value.rs
Normal file
20
ast/src/values/number_value.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::ast::{Rule, span_into_string};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_number))]
|
||||
pub struct NumberValue<'ast> {
|
||||
#[pest_ast(outer(with(span_into_string)))]
|
||||
pub value: String,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for NumberValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
39
ast/src/values/value.rs
Normal file
39
ast/src/values/value.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use crate::{ast::Rule, values::{BooleanValue, IntegerValue, FieldValue, GroupValue, NumberImplicitValue}};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value))]
|
||||
pub enum Value<'ast> {
|
||||
Integer(IntegerValue<'ast>),
|
||||
Field(FieldValue<'ast>),
|
||||
Group(GroupValue<'ast>),
|
||||
Boolean(BooleanValue<'ast>),
|
||||
Implicit(NumberImplicitValue<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> Value<'ast> {
|
||||
pub fn span(&self) -> &Span<'ast> {
|
||||
match self {
|
||||
Value::Integer(value) => &value.span,
|
||||
Value::Field(value) => &value.span,
|
||||
Value::Group(value) => &value.span,
|
||||
Value::Boolean(value) => &value.span,
|
||||
Value::Implicit(value) => &value.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Value<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Value::Integer(ref value) => write!(f, "{}", value),
|
||||
Value::Field(ref value) => write!(f, "{}", value),
|
||||
Value::Group(ref value) => write!(f, "{}", value),
|
||||
Value::Boolean(ref value) => write!(f, "{}", value),
|
||||
Value::Implicit(ref value) => write!(f, "{}", value),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
[package]
|
||||
name = "leo-benchmark"
|
||||
version = "0.1.0"
|
||||
authors = ["The Aleo Team <hello@aleo.org>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
leo-compiler = { path = "../compiler", version = "0.1.0" }
|
||||
|
||||
snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" }
|
||||
snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" }
|
||||
snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" }
|
||||
snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" }
|
||||
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
|
||||
|
||||
from-pest = { version = "0.3.1" }
|
||||
rand = { version = "0.7" }
|
@ -1,15 +0,0 @@
|
||||
struct Foo {
|
||||
x: u32
|
||||
y: u32
|
||||
}
|
||||
|
||||
function main(a: private fe) {
|
||||
let b = a + 1fe;
|
||||
assert_eq(b, 2fe);
|
||||
|
||||
let c = Foo {
|
||||
x: 4,
|
||||
y: 5,
|
||||
};
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
struct Point {
|
||||
u32 x
|
||||
u32 y
|
||||
}
|
||||
|
||||
function test() -> (u32) {
|
||||
return 5
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
use leo_compiler::{self, ast, errors::CompilerError, ParameterValue, Program};
|
||||
|
||||
use from_pest::FromPest;
|
||||
use rand::thread_rng;
|
||||
use snarkos_algorithms::snark::{
|
||||
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||
};
|
||||
use snarkos_curves::bls12_377::{Bls12_377, Fr};
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
|
||||
};
|
||||
use std::{
|
||||
fs,
|
||||
marker::PhantomData,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Benchmark<F: Field + PrimeField> {
|
||||
program: Program<F>,
|
||||
parameters: Vec<Option<ParameterValue<F>>>,
|
||||
_engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> Benchmark<F> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
program: Program::new(),
|
||||
parameters: vec![],
|
||||
_engine: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn evaluate_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Read in file as string
|
||||
let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file");
|
||||
|
||||
// Parse the file using leo.pest
|
||||
let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse");
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
||||
// println!("{:#?}", syntax_tree);
|
||||
|
||||
// Build a leo program from the syntax tree
|
||||
self.program = Program::<F>::from(syntax_tree, "simple".into());
|
||||
self.parameters = vec![None; self.program.num_parameters];
|
||||
|
||||
println!(" compiled: {:#?}\n", self.program);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Benchmark<F> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _res =
|
||||
leo_compiler::ResolvedProgram::generate_constraints(cs, self.program, self.parameters);
|
||||
println!(" Result: {}", _res);
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut setup = Duration::new(0, 0);
|
||||
let mut proving = Duration::new(0, 0);
|
||||
let mut verifying = Duration::new(0, 0);
|
||||
|
||||
let rng = &mut thread_rng();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// Load and compile program
|
||||
let mut program = Benchmark::<Fr>::new();
|
||||
program.evaluate_program().unwrap();
|
||||
|
||||
// Generate proof parameters
|
||||
let params = { generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap() };
|
||||
|
||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶ms.vk);
|
||||
|
||||
setup += start.elapsed();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// Set main function arguments in compiled program
|
||||
let argument = Some(ParameterValue::Field(Fr::one()));
|
||||
program.parameters = vec![argument];
|
||||
|
||||
// Generate proof
|
||||
let proof = create_random_proof(program, ¶ms, rng).unwrap();
|
||||
|
||||
proving += start.elapsed();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// let public_input = Fr::one();
|
||||
|
||||
// Verify proof
|
||||
let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap();
|
||||
|
||||
verifying += start.elapsed();
|
||||
|
||||
println!(" ");
|
||||
println!(" Setup time : {:?} milliseconds", setup.as_millis());
|
||||
println!(" Prover time : {:?} milliseconds", proving.as_millis());
|
||||
println!(
|
||||
" Verifier time : {:?} milliseconds",
|
||||
verifying.as_millis()
|
||||
);
|
||||
println!(" Verifier output : {}", is_success);
|
||||
println!(" ");
|
||||
|
||||
// let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
//
|
||||
// println!("\n satisfied: {:?}", cs.is_satisfied());
|
||||
//
|
||||
// println!(
|
||||
// "\n number of constraints for input: {}",
|
||||
// cs.num_constraints()
|
||||
// );
|
||||
//
|
||||
}
|
@ -5,19 +5,18 @@ authors = ["The Aleo Team <hello@aleo.org>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
leo-ast = { path = "../ast", version = "0.1.0" }
|
||||
leo-types = { path = "../types", version = "0.1.0" }
|
||||
|
||||
snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" }
|
||||
snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" }
|
||||
snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" }
|
||||
snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" }
|
||||
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
|
||||
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
|
||||
snarkos-utilities = { path = "../../snarkOS/utilities", version = "0.8.0" }
|
||||
|
||||
failure = { version = "0.1.5" }
|
||||
from-pest = { version = "0.3.1" }
|
||||
hex = { version = "0.4.2" }
|
||||
lazy_static = { version = "1.3.0" }
|
||||
log = { version = "0.4" }
|
||||
pest = { version = "2.0" }
|
||||
pest-ast = { version = "0.3.3" }
|
||||
pest_derive = { version = "2.0" }
|
||||
rand = { version = "0.7" }
|
||||
sha2 = { version = "0.8" }
|
||||
thiserror = { version = "1.0" }
|
||||
|
1109
compiler/src/ast.rs
1109
compiler/src/ast.rs
File diff suppressed because it is too large
Load Diff
@ -1,37 +1,51 @@
|
||||
//! Compiles a Leo program from a file path.
|
||||
|
||||
use crate::{ast, errors::CompilerError, ParameterValue, Program, ResolvedProgram, ResolvedValue};
|
||||
use crate::{
|
||||
constraints::{generate_constraints, generate_test_constraints, ConstrainedValue},
|
||||
errors::CompilerError,
|
||||
GroupType,
|
||||
};
|
||||
use leo_ast::LeoParser;
|
||||
use leo_types::{InputValue, Program};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
|
||||
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem, TestConstraintSystem},
|
||||
};
|
||||
|
||||
use from_pest::FromPest;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{fs, marker::PhantomData, path::PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Compiler<F: Field + PrimeField> {
|
||||
pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
|
||||
package_name: String,
|
||||
main_file_path: PathBuf,
|
||||
program: Program<F>,
|
||||
parameters: Vec<Option<ParameterValue<F>>>,
|
||||
output: Option<ResolvedValue<F>>,
|
||||
program: Program,
|
||||
program_inputs: Vec<Option<InputValue>>,
|
||||
output: Option<ConstrainedValue<F, G>>,
|
||||
_engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> Compiler<F> {
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Self {
|
||||
Self {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut program = Self {
|
||||
package_name,
|
||||
main_file_path,
|
||||
program: Program::new(),
|
||||
parameters: vec![],
|
||||
program_inputs: vec![],
|
||||
output: None,
|
||||
_engine: PhantomData,
|
||||
}
|
||||
};
|
||||
|
||||
// Generate the abstract syntax tree and assemble the program
|
||||
program.parse_program()?;
|
||||
|
||||
Ok(program)
|
||||
}
|
||||
|
||||
pub fn set_inputs(&mut self, program_inputs: Vec<Option<InputValue>>) {
|
||||
self.program_inputs = program_inputs;
|
||||
}
|
||||
|
||||
pub fn checksum(&self) -> Result<String, CompilerError> {
|
||||
@ -47,51 +61,45 @@ impl<F: Field + PrimeField> Compiler<F> {
|
||||
Ok(hex::encode(hash))
|
||||
}
|
||||
|
||||
// pub fn compile(&self) -> Result<ast::File, CompilerError> {
|
||||
// // Read in the main file as string
|
||||
// let unparsed_file = fs::read_to_string(&self.main_file_path).map_err(|_| CompilerError::FileReadError(self.main_file_path.clone()))?;
|
||||
//
|
||||
// // Parse the file using leo.pest
|
||||
// let mut file = ast::parse(&unparsed_file).map_err(|_| CompilerError::FileParsingError)?;
|
||||
//
|
||||
// // Build the abstract syntax tree
|
||||
// let syntax_tree = ast::File::from_pest(&mut file).map_err(|_| CompilerError::SyntaxTreeError)?;
|
||||
// log::debug!("{:#?}", syntax_tree);
|
||||
//
|
||||
// Ok(syntax_tree)
|
||||
// }
|
||||
pub fn compile_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<ConstrainedValue<F, G>, CompilerError> {
|
||||
generate_constraints(cs, self.program, self.program_inputs)
|
||||
}
|
||||
|
||||
pub fn evaluate_program<CS: ConstraintSystem<F>>(&mut self) -> Result<(), CompilerError> {
|
||||
// Read in the main file as string
|
||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|_| CompilerError::FileReadError(self.main_file_path.clone()))?;
|
||||
pub fn compile_test_constraints(
|
||||
self,
|
||||
cs: &mut TestConstraintSystem<F>,
|
||||
) -> Result<(), CompilerError> {
|
||||
generate_test_constraints::<F, G>(cs, self.program)
|
||||
}
|
||||
|
||||
// Parse the file using leo.pest
|
||||
let mut file = ast::parse(&unparsed_file).map_err(|_| CompilerError::FileParsingError)?;
|
||||
fn parse_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Build the program syntax tree
|
||||
let file_path = &self.main_file_path;
|
||||
let input_file = &LeoParser::load_file(file_path)?;
|
||||
let syntax_tree = LeoParser::parse_file(file_path, input_file)?;
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree =
|
||||
ast::File::from_pest(&mut file).map_err(|_| CompilerError::SyntaxTreeError)?;
|
||||
log::debug!("{:#?}", syntax_tree);
|
||||
|
||||
// Build program from abstract syntax tree
|
||||
// Build program from syntax tree
|
||||
let package_name = self.package_name.clone();
|
||||
|
||||
self.program = Program::<F>::from(syntax_tree, package_name);
|
||||
self.parameters = vec![None; self.program.num_parameters];
|
||||
self.program = Program::from(syntax_tree, package_name);
|
||||
self.program_inputs = vec![None; self.program.num_parameters];
|
||||
|
||||
log::debug!("Compilation complete\n{:#?}", self.program);
|
||||
log::debug!("Program parsing complete\n{:#?}", self.program);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> ConstraintSynthesizer<F> for Compiler<F> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _res = ResolvedProgram::generate_constraints(cs, self.program, self.parameters);
|
||||
let _result =
|
||||
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
//! Methods to enforce constraints on booleans in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::{new_variable_from_variable, ResolvedProgram, ResolvedValue},
|
||||
types::{ParameterModel, ParameterValue, Variable},
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::BooleanError,
|
||||
GroupType,
|
||||
};
|
||||
use leo_types::InputValue;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
@ -14,125 +16,97 @@ use snarkos_models::{
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, CS: ConstraintSystem<F>> ResolvedProgram<F, CS> {
|
||||
pub(crate) fn bool_from_parameter(
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn bool_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
parameter_model: ParameterModel<F>,
|
||||
parameter_value: Option<ParameterValue<F>>,
|
||||
) -> Variable<F> {
|
||||
// Check that the parameter value is the correct type
|
||||
let bool_value = parameter_value.map(|parameter| match parameter {
|
||||
ParameterValue::Boolean(b) => b,
|
||||
value => unimplemented!("expected boolean parameter, got {}", value),
|
||||
});
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
// Check that the input value is the correct type
|
||||
let bool_value = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Boolean(bool) = input {
|
||||
Some(bool)
|
||||
} else {
|
||||
return Err(BooleanError::InvalidBoolean(input.to_string()));
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Check visibility of parameter
|
||||
let name = parameter_model.variable.name.clone();
|
||||
let number = if parameter_model.private {
|
||||
// Check visibility of input
|
||||
let number = if private {
|
||||
Boolean::alloc(cs.ns(|| name), || {
|
||||
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})
|
||||
.unwrap()
|
||||
})?
|
||||
} else {
|
||||
Boolean::alloc_input(cs.ns(|| name), || {
|
||||
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})
|
||||
.unwrap()
|
||||
})?
|
||||
};
|
||||
|
||||
let parameter_variable = new_variable_from_variable(scope, ¶meter_model.variable);
|
||||
|
||||
// store each argument as variable in resolved program
|
||||
self.store_variable(parameter_variable.clone(), ResolvedValue::Boolean(number));
|
||||
|
||||
parameter_variable
|
||||
Ok(ConstrainedValue::Boolean(number))
|
||||
}
|
||||
|
||||
pub(crate) fn boolean_array_from_parameter(
|
||||
&mut self,
|
||||
_cs: &mut CS,
|
||||
_scope: String,
|
||||
_parameter_model: ParameterModel<F>,
|
||||
_parameter_value: Option<ParameterValue<F>>,
|
||||
) -> Variable<F> {
|
||||
unimplemented!("Cannot enforce boolean array as parameter")
|
||||
// // Check visibility of parameter
|
||||
// let mut array_value = vec![];
|
||||
// let name = parameter.variable.name.clone();
|
||||
// for argument in argument_array {
|
||||
// let number = if parameter.private {
|
||||
// Boolean::alloc(cs.ns(|| name), ||bool_value.ok_or(SynthesisError::AssignmentMissing).unwrap()
|
||||
// } else {
|
||||
// Boolean::alloc_input(cs.ns(|| name), || Ok(argument)).unwrap()
|
||||
// };
|
||||
//
|
||||
// array_value.push(number);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// let parameter_variable = new_variable_from_variable(scope, ¶meter.variable);
|
||||
//
|
||||
// // store array as variable in resolved program
|
||||
// self.store_variable(parameter_variable.clone(), ResolvedValue::BooleanArray(array_value));
|
||||
//
|
||||
// parameter_variable
|
||||
pub(crate) fn get_boolean_constant(bool: Boolean) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(bool)
|
||||
}
|
||||
|
||||
pub(crate) fn get_boolean_constant(bool: bool) -> ResolvedValue<F> {
|
||||
ResolvedValue::Boolean(Boolean::Constant(bool))
|
||||
}
|
||||
|
||||
pub(crate) fn evaluate_not(value: ResolvedValue<F>) -> ResolvedValue<F> {
|
||||
pub(crate) fn evaluate_not(
|
||||
value: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match value {
|
||||
ResolvedValue::Boolean(boolean) => ResolvedValue::Boolean(boolean.not()),
|
||||
value => unimplemented!("cannot enforce not on non-boolean value {}", value),
|
||||
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
||||
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_or(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ResolvedValue<F>,
|
||||
right: ResolvedValue<F>,
|
||||
) -> ResolvedValue<F> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ResolvedValue::Boolean(left_bool), ResolvedValue::Boolean(right_bool)) => {
|
||||
ResolvedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool).unwrap())
|
||||
}
|
||||
(left_value, right_value) => unimplemented!(
|
||||
"cannot enforce or on non-boolean values {} || {}",
|
||||
left_value,
|
||||
right_value
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
|
||||
),
|
||||
(left_value, right_value) => Err(BooleanError::CannotEnforce(format!(
|
||||
"{} || {}",
|
||||
left_value, right_value
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_and(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: ResolvedValue<F>,
|
||||
right: ResolvedValue<F>,
|
||||
) -> ResolvedValue<F> {
|
||||
left: ConstrainedValue<F, G>,
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ResolvedValue::Boolean(left_bool), ResolvedValue::Boolean(right_bool)) => {
|
||||
ResolvedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool).unwrap())
|
||||
}
|
||||
(left_value, right_value) => unimplemented!(
|
||||
"cannot enforce and on non-boolean values {} && {}",
|
||||
left_value,
|
||||
right_value
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
|
||||
),
|
||||
(left_value, right_value) => Err(BooleanError::CannotEnforce(format!(
|
||||
"{} && {}",
|
||||
left_value, right_value
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ResolvedValue<F> {
|
||||
ResolvedValue::Boolean(Boolean::Constant(left.eq(&right)))
|
||||
pub(crate) fn boolean_eq(left: Boolean, right: Boolean) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(Boolean::Constant(left.eq(&right)))
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_boolean_eq(&mut self, cs: &mut CS, left: Boolean, right: Boolean) {
|
||||
left.enforce_equal(cs.ns(|| format!("enforce bool equal")), &right)
|
||||
.unwrap();
|
||||
pub(crate) fn enforce_boolean_eq(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
left: Boolean,
|
||||
right: Boolean,
|
||||
) -> Result<(), BooleanError> {
|
||||
Ok(left.enforce_equal(cs.ns(|| format!("enforce bool equal")), &right)?)
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user