mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-18 22:56:58 +03:00
merge testnet3 into required types, also remove identifier type
This commit is contained in:
commit
a7c3696e90
@ -46,7 +46,7 @@ commands:
|
||||
jobs:
|
||||
check-style:
|
||||
docker:
|
||||
- image: cimg/rust:1.56.1
|
||||
- image: cimg/rust:1.59.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
@ -61,7 +61,7 @@ jobs:
|
||||
|
||||
clippy:
|
||||
docker:
|
||||
- image: cimg/rust:1.56.1
|
||||
- image: cimg/rust:1.59.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
@ -76,7 +76,7 @@ jobs:
|
||||
|
||||
# code-cov:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# environment:
|
||||
# RUSTC_BOOTSTRAP: 1
|
||||
@ -118,7 +118,7 @@ jobs:
|
||||
|
||||
leo-executable:
|
||||
docker:
|
||||
- image: cimg/rust:1.56.1
|
||||
- image: cimg/rust:1.59.0
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
@ -136,7 +136,7 @@ jobs:
|
||||
#
|
||||
# leo-new:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -149,7 +149,7 @@ jobs:
|
||||
#
|
||||
# leo-init:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -162,7 +162,7 @@ jobs:
|
||||
#
|
||||
# leo-clean:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -175,7 +175,7 @@ jobs:
|
||||
#
|
||||
# leo-setup:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -188,7 +188,7 @@ jobs:
|
||||
|
||||
# leo-add-remove:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -202,7 +202,7 @@ jobs:
|
||||
# todo (collin): uncomment after compiler refactor
|
||||
# leo-check-constraints:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -215,7 +215,7 @@ jobs:
|
||||
#
|
||||
# leo-login-logout:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -228,7 +228,7 @@ jobs:
|
||||
#
|
||||
# leo-clone:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
@ -241,7 +241,7 @@ jobs:
|
||||
#
|
||||
# leo-publish:
|
||||
# docker:
|
||||
# - image: cimg/rust:1.56.1
|
||||
# - image: cimg/rust:1.59.0
|
||||
# resource_class: xlarge
|
||||
# steps:
|
||||
# - attach_workspace:
|
||||
|
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,4 +1,5 @@
|
||||
# Force certain files to be LF
|
||||
*.leo text eol=lf
|
||||
*.out text eol=lf
|
||||
*.rs text eol=lf
|
||||
*.rs text eol=lf
|
||||
*.in text eol=lf
|
||||
|
31
.github/workflows/ci.yml
vendored
31
.github/workflows/ci.yml
vendored
@ -18,14 +18,13 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macOS-latest, windows-latest, ubuntu-latest]
|
||||
os: [macOS-latest, ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
sccache-path: /home/runner/.cache/sccache
|
||||
- os: macos-latest
|
||||
sccache-path: /Users/runner/Library/Caches/Mozilla.sccache
|
||||
- os: windows-latest
|
||||
sccache-path: "C:\\Users\\runneradmin\\AppData\\Local\\Mozilla\\sccache"
|
||||
|
||||
env:
|
||||
RUSTC_WRAPPER: sccache
|
||||
SCCACHE_CACHE_SIZE: 2G
|
||||
@ -54,14 +53,6 @@ jobs:
|
||||
brew update
|
||||
brew install sccache
|
||||
|
||||
- name: Install sccache Windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
iwr -useb get.scoop.sh | iex
|
||||
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
|
||||
scoop install sccache
|
||||
echo "C:\Users\runneradmin\scoop\shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Install Rust Stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
@ -169,6 +160,24 @@ jobs:
|
||||
- name: Stop sccache server
|
||||
run: sccache --stop-server || true
|
||||
|
||||
test-package-windows:
|
||||
name: Test Package Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Rust Stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cargo test --all
|
||||
|
||||
test-docs:
|
||||
name: Test Docs
|
||||
runs-on: ubuntu-latest
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,6 +2,8 @@
|
||||
/tmp/
|
||||
**.idea/
|
||||
*.DS_Store
|
||||
.vscode
|
||||
leo.iml
|
||||
|
||||
**/process.yml
|
||||
|
||||
|
1255
Cargo.lock
generated
1255
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
26
Cargo.toml
26
Cargo.toml
@ -46,10 +46,17 @@ version = "1.5.3"
|
||||
path = "./leo/package"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-span]
|
||||
path = "./leo/span"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.snarkvm-utilities]
|
||||
git = "https://github.com/AleoHQ/snarkVM.git"
|
||||
rev = "51633e2"
|
||||
|
||||
[dependencies.backtrace]
|
||||
version = "0.3.65"
|
||||
|
||||
[dependencies.clap]
|
||||
version = "3.1"
|
||||
|
||||
@ -59,12 +66,12 @@ version = "0.5.1"
|
||||
[dependencies.colored]
|
||||
version = "2.0"
|
||||
|
||||
[dependencies.dirs]
|
||||
version = "4.0.0"
|
||||
|
||||
[dependencies.console]
|
||||
version = "0.15.0"
|
||||
|
||||
[dependencies.dirs]
|
||||
version = "4.0.0"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.8"
|
||||
features = ["serde"]
|
||||
@ -82,11 +89,11 @@ version = "0.8"
|
||||
version = "0.6.3"
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.11.9"
|
||||
version = "0.11.10"
|
||||
features = [ "blocking", "json", "multipart" ]
|
||||
|
||||
[dependencies.self_update]
|
||||
version = "0.28.0"
|
||||
version = "0.30.0"
|
||||
features = [ "archive-zip" ]
|
||||
|
||||
[dependencies.serde]
|
||||
@ -99,6 +106,9 @@ version = "1.0"
|
||||
[dependencies.structopt]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.sys-info]
|
||||
version = "0.9.1"
|
||||
|
||||
[dependencies.toml]
|
||||
version = "0.5"
|
||||
|
||||
@ -106,11 +116,11 @@ version = "0.5"
|
||||
version = "0.1"
|
||||
|
||||
[dependencies.tracing-subscriber]
|
||||
version = "0.3.6"
|
||||
version = "0.3.11"
|
||||
features = [ "fmt" ]
|
||||
|
||||
[dependencies.zip]
|
||||
version = "0.5"
|
||||
version = "0.6"
|
||||
|
||||
[target."cfg(windows)".dependencies.ansi_term]
|
||||
version = "0.12.1"
|
||||
@ -122,7 +132,7 @@ version = "2.0.4"
|
||||
version = "0.11.2"
|
||||
|
||||
[dev-dependencies.test_dir]
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
|
@ -18,9 +18,6 @@ license = "GPL-3.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.56"
|
||||
|
||||
[dependencies]
|
||||
smallvec = { version = "1.8.0", features = ["serde"] }
|
||||
|
||||
[dependencies.leo-errors]
|
||||
path = "../../leo/errors"
|
||||
version = "1.5.3"
|
||||
@ -41,8 +38,9 @@ features = [ "derive", "rc" ]
|
||||
version = "1.0"
|
||||
features = [ "preserve_order" ]
|
||||
|
||||
[dependencies.tendril]
|
||||
version = "0.4"
|
||||
[dependencies.smallvec]
|
||||
version = "1.8.0"
|
||||
features = ["serde"]
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
@ -1,49 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An array element access expression `array[index]`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ArrayAccess {
|
||||
/// The expression, evaluating to an array, that is being indexed.
|
||||
pub array: Box<Expression>,
|
||||
/// The index in `array` that is being accessed.
|
||||
pub index: Box<Expression>,
|
||||
/// The span of the entire expression `array[index]`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ArrayAccess {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}[{}]", self.array, self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for ArrayAccess {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An access to a certain range of elements in an `array`.
|
||||
///
|
||||
/// Examples include `array[0..3]`, `array[3..]`, `array[..3]`, and `array[..]`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ArrayRangeAccess {
|
||||
/// The array to extract a range of elements from.
|
||||
pub array: Box<Expression>,
|
||||
/// The lower bound of the index-range, or the start of the array when `None`.
|
||||
pub left: Option<Box<Expression>>,
|
||||
/// The higher bound of the index-range, or the end of the array when `None`.
|
||||
pub right: Option<Box<Expression>>,
|
||||
/// A span for the entire expression `array[<range>]`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ArrayRangeAccess {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}[{}..{}]",
|
||||
self.array,
|
||||
self.left.as_ref().map(|e| e.to_string()).unwrap_or_default(),
|
||||
self.right.as_ref().map(|e| e.to_string()).unwrap_or_default()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for ArrayRangeAccess {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Identifier, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A field access expression `inner.name` to some structure with *named fields*.
|
||||
///
|
||||
/// For accesses to a positional fields in e.g., a tuple, see `TupleAccess`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct MemberAccess {
|
||||
/// The structure that the field `name` is being extracted from.
|
||||
pub inner: Box<Expression>,
|
||||
/// The name of the field to extract in `inner`.
|
||||
pub name: Identifier,
|
||||
/// The span covering all of `inner.name`.
|
||||
pub span: Span,
|
||||
// FIXME(Centril): Type information shouldn't be injected into an AST,
|
||||
// so this field should eventually be removed.
|
||||
pub type_: Option<crate::Type>,
|
||||
}
|
||||
|
||||
impl fmt::Display for MemberAccess {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.{}", self.inner, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for MemberAccess {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
mod array_access;
|
||||
pub use array_access::*;
|
||||
|
||||
mod array_range_access;
|
||||
pub use array_range_access::*;
|
||||
|
||||
mod member_access;
|
||||
pub use member_access::*;
|
||||
|
||||
mod tuple_access;
|
||||
pub use tuple_access::*;
|
||||
|
||||
mod static_access;
|
||||
pub use static_access::*;
|
@ -1,49 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Node, PositiveNumber};
|
||||
use leo_span::Span;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An tuple access expression, e.g., `tuple.index`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TupleAccess {
|
||||
/// An expression evaluating to some tuple type, e.g., `(5, 2)`.
|
||||
pub tuple: Box<Expression>,
|
||||
/// The index to access in the tuple expression. E.g., `0` for `(5, 2)` would yield `5`.
|
||||
pub index: PositiveNumber,
|
||||
/// The span for the entire expression `tuple.index`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for TupleAccess {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.{}", self.tuple, self.index)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for TupleAccess {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Type};
|
||||
use leo_span::Span;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A type alias `type name = represents;`.
|
||||
///
|
||||
/// That is, `name` will become another name for `represents`.
|
||||
/// This does not create a new type, that is, `name` is the same type as `represents`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Alias {
|
||||
/// The new name for `represents`.
|
||||
pub name: Identifier,
|
||||
/// A span for the entire `type name = represents;`.
|
||||
pub span: Span,
|
||||
/// The type that `name` will evaluate and is equal to.
|
||||
pub represents: Type,
|
||||
}
|
||||
|
||||
impl fmt::Display for Alias {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{} : {}", self.name.name, self.represents)
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod alias;
|
||||
pub use self::alias::*;
|
@ -1,52 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Identifier;
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// An annotation `@name (arguments)?`.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Annotation {
|
||||
/// The span including `name ( arguments )`.
|
||||
pub span: Span,
|
||||
/// The name of the annotation.
|
||||
pub name: Identifier,
|
||||
/// Arguments for the annotation, if any.
|
||||
pub arguments: Vec<Symbol>,
|
||||
}
|
||||
|
||||
/// The set of allowed annotations.
|
||||
const ALLOWED_ANNOTATIONS: &[Symbol] = &[sym::test];
|
||||
|
||||
impl Annotation {
|
||||
/// Is the annotation valid?
|
||||
pub fn is_valid_annotation(&self) -> bool {
|
||||
ALLOWED_ANNOTATIONS.iter().any(|name| self.name.name == *name)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Annotation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "@{:}(", self.name)?;
|
||||
for arg in &self.arguments {
|
||||
write!(f, "{:},", arg)?;
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
@ -48,11 +48,23 @@ impl fmt::Display for Char {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Scalar(c) => write!(f, "{}", c),
|
||||
Self::NonScalar(c) => write!(f, "{}", c),
|
||||
Self::NonScalar(c) => write!(f, "{:X}", c),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Chars(pub Vec<Char>);
|
||||
|
||||
impl fmt::Display for Chars {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for character in self.0.iter() {
|
||||
write!(f, "{}", character)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CharValue {
|
||||
pub character: Char,
|
||||
|
@ -1,56 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{CircuitMember, Identifier};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A record type definition, e.g., `circuit Foo { my_field: Bar }`.
|
||||
/// In some languages these are called `struct`s.
|
||||
///
|
||||
/// Type identity is decided by the full path including `circuit_name`,
|
||||
/// as the record is nominal, not structural.
|
||||
/// The fields are named so `circuit Foo(u8, u16)` is not allowed.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Circuit {
|
||||
/// The name of the type in the type system in this module.
|
||||
pub circuit_name: Identifier,
|
||||
/// The fields, constant variables, and functions of this structure.
|
||||
pub members: Vec<CircuitMember>,
|
||||
}
|
||||
|
||||
impl Circuit {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "circuit {} {{ ", self.circuit_name)?;
|
||||
for field in self.members.iter() {
|
||||
writeln!(f, " {}", field)?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Circuit {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Circuit {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Function, Identifier, Type};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
/// A member of a circuit definition.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CircuitMember {
|
||||
/// A static constant in a circuit.
|
||||
/// For example: `const foobar: u8 = 42;`.
|
||||
CircuitConst(
|
||||
/// The identifier of the constant.
|
||||
Identifier,
|
||||
/// The type the constant has.
|
||||
Type,
|
||||
/// The expression representing the constant's value.
|
||||
/// Checked to be of the type above.
|
||||
Expression,
|
||||
),
|
||||
/// A varible definition in a circuit;
|
||||
/// For example: `foobar: u8;`.
|
||||
CircuitVariable(
|
||||
/// The identifier of the constant.
|
||||
Identifier,
|
||||
/// The type the constant has.
|
||||
Type,
|
||||
),
|
||||
/// A function definition in a circuit.
|
||||
/// For example: `function bar() -> u8 { return 2u8; }`.
|
||||
CircuitFunction(
|
||||
/// The function.
|
||||
Box<Function>,
|
||||
),
|
||||
}
|
||||
|
||||
impl fmt::Display for CircuitMember {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CircuitMember::CircuitConst(ref identifier, ref type_, ref value) => {
|
||||
write!(f, "{}: {} = {}", identifier, type_, value)
|
||||
}
|
||||
CircuitMember::CircuitVariable(ref identifier, ref type_) => write!(f, "{}: {}", identifier, type_),
|
||||
CircuitMember::CircuitFunction(ref function) => write!(f, "{}", function),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Identifier};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CircuitVariableDefinition {
|
||||
pub identifier: Identifier,
|
||||
pub expression: Expression,
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::PositiveNumber;
|
||||
|
||||
use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{fmt, ops::Deref};
|
||||
|
||||
/// Specifies array dimensions for array [`Type`]s or in array initializer [`Expression`]s.
|
||||
#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ArrayDimensions(pub SmallVec<[PositiveNumber; 1]>);
|
||||
|
||||
impl Deref for ArrayDimensions {
|
||||
type Target = [PositiveNumber];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ArrayDimensions {
|
||||
/// Returns a single-dimensional array dimension.
|
||||
pub fn single(dim: PositiveNumber) -> Self {
|
||||
Self(smallvec![dim])
|
||||
}
|
||||
|
||||
/// Returns `true` if there is an array dimension equal to zero.
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.iter().any(|d| d.is_zero())
|
||||
}
|
||||
|
||||
/// Attempts to remove the first dimension from the array, or returns `None` if it doesn't.
|
||||
pub fn remove_first(&mut self) -> Option<PositiveNumber> {
|
||||
if self.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.0.remove(0))
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to remove the last dimension from the array, or returns `None` if it doesn't.
|
||||
pub fn remove_last(&mut self) -> Option<PositiveNumber> {
|
||||
self.0.pop()
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom Serializer for ArrayDimensions is required to ignore internal ArrayDimension nodes in the AST.
|
||||
impl Serialize for ArrayDimensions {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
|
||||
for dim in self.0.iter() {
|
||||
seq.serialize_element(&dim)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ArrayDimensions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match &*self.0 {
|
||||
[dim] => write!(f, "{}", dim),
|
||||
dimensions => write!(
|
||||
f,
|
||||
"({})",
|
||||
dimensions.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ")
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The `self` keyword can view circuit values inside of a circuit function.
|
||||
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
#[serde(transparent)]
|
||||
pub struct ConstSelfKeyword {
|
||||
/// Always `const self`.
|
||||
pub identifier: Identifier,
|
||||
}
|
||||
|
||||
impl fmt::Display for ConstSelfKeyword {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "const self")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for ConstSelfKeyword {
|
||||
fn span(&self) -> &Span {
|
||||
&self.identifier.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.identifier.span = span;
|
||||
}
|
||||
}
|
@ -32,13 +32,13 @@ use std::{
|
||||
/// An identifier in the constrained program.
|
||||
///
|
||||
/// Attention - When adding or removing fields from this struct,
|
||||
/// please remember to update it's Serialize and Deserialize implementation
|
||||
/// please remember to update its Serialize and Deserialize implementation
|
||||
/// to reflect the new struct instantiation.
|
||||
#[derive(Clone)]
|
||||
pub struct Identifier {
|
||||
/// The symbol that the user wrote, e.g., `foo`.
|
||||
pub name: Symbol,
|
||||
/// A span locating where the identifier occured in the source.
|
||||
/// A span locating where the identifier occurred in the source.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
|
@ -14,12 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod array_dimensions;
|
||||
pub use array_dimensions::*;
|
||||
|
||||
pub mod const_self_keyword;
|
||||
pub use const_self_keyword::*;
|
||||
|
||||
pub mod global_consts_json;
|
||||
|
||||
pub mod identifier;
|
||||
@ -28,16 +22,5 @@ pub use identifier::*;
|
||||
pub mod imported_modules;
|
||||
pub use imported_modules::*;
|
||||
|
||||
pub mod mut_self_keyword;
|
||||
pub use mut_self_keyword::*;
|
||||
|
||||
pub mod positive_number;
|
||||
pub use positive_number::*;
|
||||
|
||||
pub mod self_keyword;
|
||||
pub use self_keyword::*;
|
||||
|
||||
pub mod spread_or_expression;
|
||||
pub use spread_or_expression::*;
|
||||
|
||||
pub mod vec_tendril_json;
|
||||
|
@ -1,45 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The `&self` keyword can view and modify circuit values inside of a circuit function.
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
#[serde(transparent)]
|
||||
pub struct RefSelfKeyword {
|
||||
/// Always `&self`.
|
||||
pub identifier: Identifier,
|
||||
}
|
||||
|
||||
impl fmt::Display for RefSelfKeyword {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "&self")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for RefSelfKeyword {
|
||||
fn span(&self) -> &Span {
|
||||
&self.identifier.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.identifier.span = span;
|
||||
}
|
||||
}
|
@ -16,21 +16,19 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// A number string guaranteed to be positive by the pest grammar.
|
||||
/// A number string guaranteed to be positive.
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct PositiveNumber {
|
||||
/// The string representation of the positive number.
|
||||
// FIXME(Centril): This should become an `u128`.
|
||||
#[serde(with = "leo_span::tendril_json")]
|
||||
pub value: StrTendril,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl PositiveNumber {
|
||||
/// Returns `true` if this number is zero.
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.value.as_ref().eq("0")
|
||||
self.value.eq("0")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The `self` keyword can view circuit values inside of a circuit function.
|
||||
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
#[serde(transparent)]
|
||||
pub struct SelfKeyword {
|
||||
/// Always just `self`.
|
||||
pub identifier: Identifier,
|
||||
}
|
||||
|
||||
impl fmt::Display for SelfKeyword {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "self")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for SelfKeyword {
|
||||
fn span(&self) -> &Span {
|
||||
&self.identifier.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.identifier.span = span;
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Expression, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Either a spread expression or a normal expression.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum SpreadOrExpression {
|
||||
/// A spread expression, i.e., `...other_array`.
|
||||
Spread(Expression),
|
||||
/// A normal element expression.
|
||||
Expression(Expression),
|
||||
}
|
||||
|
||||
impl fmt::Display for SpreadOrExpression {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for SpreadOrExpression {
|
||||
fn span(&self) -> &Span {
|
||||
use SpreadOrExpression::*;
|
||||
match self {
|
||||
Spread(expression) | Expression(expression) => expression.span(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
use SpreadOrExpression::*;
|
||||
match self {
|
||||
Spread(expression) | Expression(expression) => expression.set_span(span),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use tendril::StrTendril;
|
||||
|
||||
#[allow(clippy::ptr_arg)]
|
||||
pub fn serialize<S: Serializer>(tendril: &Vec<StrTendril>, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
tendril
|
||||
.iter()
|
||||
.map(|x| x.as_ref())
|
||||
.collect::<Vec<_>>()
|
||||
.serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<StrTendril>, D::Error> {
|
||||
Ok(Vec::<String>::deserialize(deserializer)?
|
||||
.into_iter()
|
||||
.map(|x| x.into())
|
||||
.collect())
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use crate::accesses::*;
|
||||
|
||||
/// An access expressions, extracting a smaller part out of a whole.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum AccessExpression {
|
||||
/// An `array[index]` expression.
|
||||
Array(ArrayAccess),
|
||||
/// An expression accessing a range of an array.
|
||||
ArrayRange(ArrayRangeAccess),
|
||||
/// An expression accessing a field in a structure, e.g., `circuit_var.field`.
|
||||
Member(MemberAccess),
|
||||
/// Access to a tuple field using its position, e.g., `tuple.1`.
|
||||
Tuple(TupleAccess),
|
||||
/// Access to a member constant or a static function of a circuit.
|
||||
Static(StaticAccess),
|
||||
}
|
||||
|
||||
impl fmt::Display for AccessExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use AccessExpression::*;
|
||||
|
||||
match self {
|
||||
Array(access) => access.fmt(f),
|
||||
ArrayRange(access) => access.fmt(f),
|
||||
Member(access) => access.fmt(f),
|
||||
Tuple(access) => access.fmt(f),
|
||||
Static(access) => access.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for AccessExpression {
|
||||
fn span(&self) -> &Span {
|
||||
use AccessExpression::*;
|
||||
|
||||
match &self {
|
||||
Array(access) => access.span(),
|
||||
ArrayRange(access) => access.span(),
|
||||
Member(access) => access.span(),
|
||||
Tuple(access) => access.span(),
|
||||
Static(access) => access.span(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
use AccessExpression::*;
|
||||
|
||||
match self {
|
||||
Array(access) => access.set_span(span),
|
||||
ArrayRange(access) => access.set_span(span),
|
||||
Member(access) => access.set_span(span),
|
||||
Tuple(access) => access.set_span(span),
|
||||
Static(access) => access.set_span(span),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
|
||||
/// An array initializer expression, e.g., `[42; 5]`.
|
||||
/// constructing an array of `element` repeated according to `dimensions`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ArrayInitExpression {
|
||||
/// The expression that all elements in the array will evaluate to.
|
||||
pub element: Box<Expression>,
|
||||
/// The dimensions of the array.
|
||||
///
|
||||
/// This could be a multi-dimensional array,
|
||||
/// e.g., `[42; (2, 2)]`, giving you a matrix `[[42, 42], [42, 42]]`.
|
||||
pub dimensions: ArrayDimensions,
|
||||
/// The span of the entire expression from `[` to `]`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ArrayInitExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{}; {}]", self.element, self.dimensions)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for ArrayInitExpression {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
|
||||
/// An expression constructing an array by listing the individual elements inline,
|
||||
/// for example `[4, 6, 5, 2]`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ArrayInlineExpression {
|
||||
/// A list, where a part can be either an element,
|
||||
/// or list of elements to construct the array with.
|
||||
pub elements: Vec<SpreadOrExpression>,
|
||||
/// The span of the entire expression from `[` to `]`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ArrayInlineExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[")?;
|
||||
for (i, e) in self.elements.iter().enumerate() {
|
||||
write!(f, "{}", e)?;
|
||||
if i < self.elements.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, "]")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for ArrayInlineExpression {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Type;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// A cast expression `e as U`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CastExpression {
|
||||
/// The expression `e` of a type `T` that is being cast to `U`.
|
||||
pub inner: Box<Expression>,
|
||||
/// The type `U` to cast `e` to.
|
||||
pub target_type: Type,
|
||||
/// Span for the entire expression `e as U` to.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for CastExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} as {}", self.inner, self.target_type)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for CastExpression {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
|
||||
/// An initializer for a single field / variable of a circuit initializer expression.
|
||||
/// That is, in `Foo { bar: 42, baz }`, this is either `bar: 42`, or `baz`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CircuitVariableInitializer {
|
||||
/// The name of the field / variable to be initialized.
|
||||
pub identifier: Identifier,
|
||||
/// The expression to initialize the field with.
|
||||
/// When `None`, a binding, in scope, with the name will be used instead.
|
||||
pub expression: Option<Expression>,
|
||||
}
|
||||
|
||||
impl fmt::Display for CircuitVariableInitializer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(expr) = &self.expression {
|
||||
write!(f, "{}: {}", self.identifier, expr)
|
||||
} else {
|
||||
write!(f, "{}", self.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A circuit initialization expression, e.g., `Foo { bar: 42, baz }`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CircuitInitExpression {
|
||||
/// The name of the structure type to initialize.
|
||||
pub name: Identifier,
|
||||
/// Initializer expressions for each of the fields in the circuit.
|
||||
///
|
||||
/// N.B. Any functions or member constants in the circuit definition
|
||||
/// are excluded from this list.
|
||||
pub members: Vec<CircuitVariableInitializer>,
|
||||
/// A span from `name` to `}`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for CircuitInitExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {{", self.name)?;
|
||||
for member in self.members.iter() {
|
||||
write!(f, "{}", member)?;
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for CircuitInitExpression {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -14,35 +14,23 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ArrayDimensions, GroupValue, Identifier, IntegerType, Node, SpreadOrExpression};
|
||||
use crate::{GroupValue, Identifier, IntegerType, Node};
|
||||
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
mod accesses;
|
||||
pub use accesses::*;
|
||||
mod binary;
|
||||
pub use binary::*;
|
||||
mod unary;
|
||||
pub use unary::*;
|
||||
mod ternary;
|
||||
pub use ternary::*;
|
||||
mod array_inline;
|
||||
pub use array_inline::*;
|
||||
mod array_init;
|
||||
pub use array_init::*;
|
||||
mod tuple_init;
|
||||
pub use tuple_init::*;
|
||||
mod circuit_init;
|
||||
pub use circuit_init::*;
|
||||
mod value;
|
||||
pub use value::*;
|
||||
mod call;
|
||||
pub use call::*;
|
||||
mod cast;
|
||||
pub use cast::*;
|
||||
mod err;
|
||||
pub use err::*;
|
||||
|
||||
@ -59,19 +47,6 @@ pub enum Expression {
|
||||
Unary(UnaryExpression),
|
||||
/// A ternary conditional expression `cond ? if_expr : else_expr`.
|
||||
Ternary(TernaryExpression),
|
||||
/// A cast expression `expr as type`.
|
||||
Cast(CastExpression),
|
||||
/// An access expression of some sort, e.g., `array[idx]` or `foo.bar`.
|
||||
Access(AccessExpression),
|
||||
/// An array expression where individual elements are listed inline,
|
||||
/// for example `[4, 6, ...[5, 7], 2]`.
|
||||
ArrayInline(ArrayInlineExpression),
|
||||
/// An array-repeat expression, e.g., `[42; 3]` yielding `[42, 42, 42]`.
|
||||
ArrayInit(ArrayInitExpression),
|
||||
/// A tuple expression e.g., `(foo, 42, true)`.
|
||||
TupleInit(TupleInitExpression),
|
||||
/// An expression constructing a structure like `Foo { bar: 42, baz }`.
|
||||
CircuitInit(CircuitInitExpression),
|
||||
/// A call expression like `my_fun(args)`.
|
||||
Call(CallExpression),
|
||||
/// An expression of type "error".
|
||||
@ -88,13 +63,7 @@ impl Node for Expression {
|
||||
Binary(n) => n.span(),
|
||||
Unary(n) => n.span(),
|
||||
Ternary(n) => n.span(),
|
||||
ArrayInline(n) => n.span(),
|
||||
ArrayInit(n) => n.span(),
|
||||
TupleInit(n) => n.span(),
|
||||
CircuitInit(n) => n.span(),
|
||||
Call(n) => n.span(),
|
||||
Cast(n) => n.span(),
|
||||
Access(n) => n.span(),
|
||||
Err(n) => n.span(),
|
||||
}
|
||||
}
|
||||
@ -107,13 +76,7 @@ impl Node for Expression {
|
||||
Binary(n) => n.set_span(span),
|
||||
Unary(n) => n.set_span(span),
|
||||
Ternary(n) => n.set_span(span),
|
||||
ArrayInline(n) => n.set_span(span),
|
||||
ArrayInit(n) => n.set_span(span),
|
||||
TupleInit(n) => n.set_span(span),
|
||||
CircuitInit(n) => n.set_span(span),
|
||||
Call(n) => n.set_span(span),
|
||||
Cast(n) => n.set_span(span),
|
||||
Access(n) => n.set_span(span),
|
||||
Err(n) => n.set_span(span),
|
||||
}
|
||||
}
|
||||
@ -128,13 +91,7 @@ impl fmt::Display for Expression {
|
||||
Binary(n) => n.fmt(f),
|
||||
Unary(n) => n.fmt(f),
|
||||
Ternary(n) => n.fmt(f),
|
||||
ArrayInline(n) => n.fmt(f),
|
||||
ArrayInit(n) => n.fmt(f),
|
||||
TupleInit(n) => n.fmt(f),
|
||||
CircuitInit(n) => n.fmt(f),
|
||||
Call(n) => n.fmt(f),
|
||||
Cast(n) => n.fmt(f),
|
||||
Access(n) => n.fmt(f),
|
||||
Err(n) => n.fmt(f),
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
|
||||
/// A tuple construction expression, e.g., `(foo, false, 42)`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TupleInitExpression {
|
||||
/// The elements of the tuple.
|
||||
/// In the example above, it would be `foo`, `false`, and `42`.
|
||||
pub elements: Vec<Expression>,
|
||||
/// The span from `(` to `)`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for TupleInitExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "(")?;
|
||||
for (i, member) in self.elements.iter().enumerate() {
|
||||
write!(f, "{}", member)?;
|
||||
if i < self.elements.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for TupleInitExpression {
|
||||
fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
}
|
@ -14,8 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use tendril::StrTendril;
|
||||
|
||||
use super::*;
|
||||
use crate::{Char, CharValue};
|
||||
|
||||
@ -24,37 +22,21 @@ use crate::{Char, CharValue};
|
||||
pub enum ValueExpression {
|
||||
// todo: deserialize values here
|
||||
/// An address literal, e.g., `aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8`.
|
||||
Address(
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Address(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A boolean literal, either `true` or `false`.
|
||||
Boolean(
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Boolean(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A char literal, e.g., `'a'`, representing a single unicode code point.
|
||||
Char(CharValue),
|
||||
/// A field literal, e.g., `42field`.
|
||||
/// That is, a signed number followed by the keyword `field`.
|
||||
Field(
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Field(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A group literal, either product or affine.
|
||||
/// For example, `42group` or `(12, 52)group`.
|
||||
Group(Box<GroupValue>),
|
||||
/// A negated non-integer literal, e.g., `-4.2`.
|
||||
Implicit(
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Implicit(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// An integer literal, e.g., `42`.
|
||||
Integer(
|
||||
IntegerType,
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Integer(IntegerType, String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A string literal, e.g., `"foobar"`.
|
||||
String(Vec<Char>, #[serde(with = "leo_span::span_json")] Span),
|
||||
}
|
||||
|
@ -14,10 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Annotation, Block, FunctionInput, Identifier, Node, Type};
|
||||
use crate::{Block, FunctionInput, Identifier, Node, Type};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
@ -25,8 +24,6 @@ use std::fmt;
|
||||
/// A function definition.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Function {
|
||||
/// A map of all the annotations from their base names to the whole.
|
||||
pub annotations: IndexMap<Symbol, Annotation>,
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
pub identifier: Identifier,
|
||||
/// The function's parameters.
|
||||
@ -63,29 +60,6 @@ impl Function {
|
||||
self.name() == sym::main
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function has input `self` or `mut self`.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn contains_self(&self) -> bool {
|
||||
self.input.iter().any(|param| param.is_self())
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function has input `mut self`.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn contains_mut_self(&self) -> bool {
|
||||
self.input.iter().any(|param| param.is_mut_self())
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns an iterator of [&FunctionInput] removing `self` and `mut self` inputs.
|
||||
///
|
||||
pub fn filter_self_inputs(&self) -> impl Iterator<Item = &FunctionInput> {
|
||||
self.input.iter().filter(|input| !input.is_self())
|
||||
}
|
||||
|
||||
///
|
||||
/// Private formatting method used for optimizing [fmt::Debug] and [fmt::Display] implementations.
|
||||
///
|
||||
|
@ -20,30 +20,60 @@ use leo_span::Span;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ParamMode {
|
||||
Constant,
|
||||
Private,
|
||||
Public,
|
||||
}
|
||||
|
||||
impl fmt::Display for ParamMode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use ParamMode::*;
|
||||
|
||||
match self {
|
||||
Constant => write!(f, "constant"),
|
||||
Private => write!(f, "private"),
|
||||
Public => write!(f, "public"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A function parameter.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FunctionInputVariable {
|
||||
/// The name the parameter is accessible as in the function's body.
|
||||
pub identifier: Identifier,
|
||||
/// Is it a const parameter?
|
||||
pub const_: bool,
|
||||
/// Is it a mutable parameter?
|
||||
pub mutable: bool,
|
||||
/// The mode of the function parameter.
|
||||
mode: ParamMode,
|
||||
/// What's the parameter's type?
|
||||
pub type_: Type,
|
||||
type_: Type,
|
||||
/// The parameters span from any annotations to its type.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl FunctionInputVariable {
|
||||
pub fn new(identifier: Identifier, mode: ParamMode, type_: Type, span: Span) -> Self {
|
||||
Self {
|
||||
identifier,
|
||||
mode,
|
||||
type_,
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mode(&self) -> ParamMode {
|
||||
self.mode
|
||||
}
|
||||
|
||||
pub fn type_(&self) -> Type {
|
||||
self.type_.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FunctionInputVariable {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// mut var: bool
|
||||
if self.const_ {
|
||||
write!(f, "const ")?;
|
||||
}
|
||||
if self.mutable {
|
||||
write!(f, "mut ")?;
|
||||
}
|
||||
write!(f, "{} ", self.mode)?;
|
||||
write!(f, "{}: ", self.identifier)?;
|
||||
write!(f, "{}", self.type_)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ConstSelfKeyword, FunctionInputVariable, Node, RefSelfKeyword, SelfKeyword};
|
||||
use crate::{FunctionInputVariable, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -23,74 +23,24 @@ use std::fmt;
|
||||
/// Enumerates the possible inputs to a function.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub enum FunctionInput {
|
||||
/// A `self` parameter.
|
||||
SelfKeyword(SelfKeyword),
|
||||
/// A `const self` parameter.
|
||||
ConstSelfKeyword(ConstSelfKeyword),
|
||||
/// A `&self` parameter.
|
||||
RefSelfKeyword(RefSelfKeyword),
|
||||
/// A normal function parameter.
|
||||
Variable(FunctionInputVariable),
|
||||
}
|
||||
|
||||
impl FunctionInput {
|
||||
///
|
||||
/// Returns `true` if the function input is the `self` or `mut self` keyword.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn is_self(&self) -> bool {
|
||||
match self {
|
||||
FunctionInput::SelfKeyword(_) => true,
|
||||
FunctionInput::ConstSelfKeyword(_) => true,
|
||||
FunctionInput::RefSelfKeyword(_) => true,
|
||||
FunctionInput::Variable(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function input is the `const self` keyword.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn is_const_self(&self) -> bool {
|
||||
match self {
|
||||
FunctionInput::SelfKeyword(_) => false,
|
||||
FunctionInput::ConstSelfKeyword(_) => true,
|
||||
FunctionInput::RefSelfKeyword(_) => false,
|
||||
FunctionInput::Variable(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the function input is the `mut self` keyword.
|
||||
/// Returns `false` otherwise.
|
||||
///
|
||||
pub fn is_mut_self(&self) -> bool {
|
||||
match self {
|
||||
FunctionInput::SelfKeyword(_) => false,
|
||||
FunctionInput::ConstSelfKeyword(_) => false,
|
||||
FunctionInput::RefSelfKeyword(_) => true,
|
||||
FunctionInput::Variable(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns Option with FunctionInputVariable if the input is a variable.
|
||||
/// Returns None otherwise.
|
||||
///
|
||||
pub fn get_variable(&self) -> Option<&FunctionInputVariable> {
|
||||
if let FunctionInput::Variable(var) = self {
|
||||
Some(var)
|
||||
} else {
|
||||
None
|
||||
pub fn get_variable(&self) -> &FunctionInputVariable {
|
||||
match self {
|
||||
Self::Variable(var) => var,
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats the parameter to `f`.
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
FunctionInput::SelfKeyword(keyword) => write!(f, "{}", keyword),
|
||||
FunctionInput::ConstSelfKeyword(keyword) => write!(f, "{}", keyword),
|
||||
FunctionInput::RefSelfKeyword(keyword) => write!(f, "{}", keyword),
|
||||
FunctionInput::Variable(function_input) => write!(f, "{}", function_input),
|
||||
}
|
||||
}
|
||||
@ -112,11 +62,7 @@ impl PartialEq for FunctionInput {
|
||||
/// Returns true if `self == other`. Does not compare spans.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(FunctionInput::SelfKeyword(_), FunctionInput::SelfKeyword(_)) => true,
|
||||
(FunctionInput::ConstSelfKeyword(_), FunctionInput::ConstSelfKeyword(_)) => true,
|
||||
(FunctionInput::RefSelfKeyword(_), FunctionInput::RefSelfKeyword(_)) => true,
|
||||
(FunctionInput::Variable(left), FunctionInput::Variable(right)) => left.eq(right),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,9 +73,6 @@ impl Node for FunctionInput {
|
||||
fn span(&self) -> &Span {
|
||||
use FunctionInput::*;
|
||||
match self {
|
||||
SelfKeyword(keyword) => &keyword.identifier.span,
|
||||
ConstSelfKeyword(keyword) => &keyword.identifier.span,
|
||||
RefSelfKeyword(keyword) => &keyword.identifier.span,
|
||||
Variable(variable) => &variable.span,
|
||||
}
|
||||
}
|
||||
@ -137,9 +80,6 @@ impl Node for FunctionInput {
|
||||
fn set_span(&mut self, span: Span) {
|
||||
use FunctionInput::*;
|
||||
match self {
|
||||
SelfKeyword(keyword) => keyword.identifier.span = span,
|
||||
ConstSelfKeyword(keyword) => keyword.identifier.span = span,
|
||||
RefSelfKeyword(keyword) => keyword.identifier.span = span,
|
||||
Variable(variable) => variable.span = span,
|
||||
}
|
||||
}
|
||||
|
@ -18,16 +18,12 @@ use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// A coordinate in a affine group literal.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupCoordinate {
|
||||
/// A number, e.g., `42`.
|
||||
Number(
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Number(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// A sign high recovery, i.e. `+`.
|
||||
SignHigh,
|
||||
/// A sign low recovery, i.e., `-`.
|
||||
|
@ -19,16 +19,12 @@ use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use tendril::StrTendril;
|
||||
|
||||
/// A group literal.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum GroupValue {
|
||||
/// Product group literal, e.g., `42group`.
|
||||
Single(
|
||||
#[serde(with = "leo_span::tendril_json")] StrTendril,
|
||||
#[serde(with = "leo_span::span_json")] Span,
|
||||
),
|
||||
Single(String, #[serde(with = "leo_span::span_json")] Span),
|
||||
/// An affine group literal with (x, y) coordinates.
|
||||
Tuple(GroupTuple),
|
||||
}
|
||||
|
@ -1,119 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::Identifier;
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Represents an import statement in a Leo program.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImportStatement {
|
||||
/// The tree specifying what items or packages to import.
|
||||
pub tree: ImportTree,
|
||||
/// The span, excluding the `;`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ImportStatement {
|
||||
/// Returns the the package file name of the self import statement.
|
||||
pub fn get_file_name(&self) -> Symbol {
|
||||
self.tree.base.first().unwrap().name
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ImportStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "import {};", self.tree)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ImportStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// An import tree specifies item(s) to import.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImportTree {
|
||||
/// A path to the base item or package to import or import from.
|
||||
/// The list is always non-empty.
|
||||
pub base: Vec<Identifier>,
|
||||
/// Specifies the kind of import and the meaning of `base`.
|
||||
/// This includes plain imports, renames, globs (`*`), and nested imports.
|
||||
pub kind: ImportTreeKind,
|
||||
/// The span for the import excluding `import` and `;`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for ImportTree {
|
||||
/// Formats `self` to `f`.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Format the path.
|
||||
for (i, part) in self.base.iter().enumerate() {
|
||||
write!(f, "{}", part)?;
|
||||
if i < self.base.len() - 1 {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
|
||||
// Format the kind.
|
||||
match &self.kind {
|
||||
ImportTreeKind::Glob { .. } => write!(f, ".*"),
|
||||
ImportTreeKind::Leaf { alias: None } => Ok(()),
|
||||
ImportTreeKind::Leaf { alias: Some(alias) } => write!(f, "as {}", alias),
|
||||
ImportTreeKind::Nested { tree } => {
|
||||
write!(f, ".(")?;
|
||||
for (i, node) in tree.iter().enumerate() {
|
||||
write!(f, "{}", node)?;
|
||||
if i < tree.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ImportTree {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies the import kind and the meaning of `base`.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ImportTreeKind {
|
||||
/// A glob import `*`.
|
||||
Glob {
|
||||
/// The span for the `*`.
|
||||
span: Span,
|
||||
},
|
||||
/// A leaf package to import.
|
||||
Leaf {
|
||||
/// When specified, the package is imported under a different name.
|
||||
/// Otherwise, the `base` name is used as in the `ImportTree`.
|
||||
alias: Option<Identifier>,
|
||||
},
|
||||
/// A nested import of items or sub-packages.
|
||||
Nested {
|
||||
/// The sub-tree specifying what to import from the `base`.
|
||||
tree: Vec<ImportTree>,
|
||||
},
|
||||
}
|
@ -15,12 +15,13 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use crate::{Expression, Identifier, Type};
|
||||
use crate::{Expression, Identifier, ParamMode, Type};
|
||||
|
||||
/// A single definition inside a section in a state or an input file.
|
||||
/// Definitions should be structured as: `<name>: <type_> = <value>;`
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Definition {
|
||||
pub mode: ParamMode,
|
||||
pub type_: Type,
|
||||
pub name: Identifier,
|
||||
pub value: Expression,
|
||||
|
@ -14,8 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{normalize_json_value, remove_key_from_json};
|
||||
|
||||
use super::*;
|
||||
use leo_errors::AstError;
|
||||
use leo_errors::{AstError, Result};
|
||||
|
||||
/// Input data which includes [`ProgramInput`] and [`ProgramState`].
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
@ -24,16 +26,44 @@ pub struct Input {
|
||||
pub program_state: ProgramState,
|
||||
}
|
||||
|
||||
/// A raw unprocessed input or state file data. Used for future conversion
|
||||
/// into [`ProgramInput`] or [`ProgramState`].
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ParsedInputFile {
|
||||
pub sections: Vec<Section>,
|
||||
}
|
||||
|
||||
impl Input {
|
||||
/// Serializes the ast into a JSON string.
|
||||
pub fn to_json_string(&self) -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(&self).map_err(|e| AstError::failed_to_convert_ast_to_json_string(&e))?)
|
||||
}
|
||||
}
|
||||
|
||||
/// A raw unprocessed input or state file data. Used for future conversion
|
||||
/// into [`ProgramInput`] or [`ProgramState`].
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct InputAst {
|
||||
pub sections: Vec<Section>,
|
||||
}
|
||||
|
||||
impl InputAst {
|
||||
/// Serializes the `Input` into a JSON Value.
|
||||
pub fn to_json_value(&self) -> Result<serde_json::Value> {
|
||||
Ok(serde_json::to_value(&self).map_err(|e| AstError::failed_to_convert_ast_to_json_value(&e))?)
|
||||
}
|
||||
|
||||
/// Serializes the `Input` into a JSON value and removes keys from object mappings before writing to a file.
|
||||
pub fn to_json_file_without_keys(
|
||||
&self,
|
||||
mut path: std::path::PathBuf,
|
||||
file_name: &str,
|
||||
excluded_keys: &[&str],
|
||||
) -> Result<()> {
|
||||
path.push(file_name);
|
||||
let file = std::fs::File::create(&path).map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e))?;
|
||||
let writer = std::io::BufWriter::new(file);
|
||||
|
||||
let mut value = self.to_json_value().unwrap();
|
||||
for key in excluded_keys {
|
||||
value = remove_key_from_json(value, key);
|
||||
}
|
||||
value = normalize_json_value(value);
|
||||
|
||||
Ok(serde_json::to_writer_pretty(writer, &value)
|
||||
.map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e))?)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{CharValue, Expression, GroupValue, IntegerType, Node, SpreadOrExpression, Type, ValueExpression};
|
||||
use crate::{CharValue, Expression, GroupValue, IntegerType, Node, Type, UnaryOperation, ValueExpression};
|
||||
use leo_errors::{InputError, LeoError, ParserError, Result};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -28,8 +28,6 @@ pub enum InputValue {
|
||||
Field(String),
|
||||
Group(GroupValue),
|
||||
Integer(IntegerType, String),
|
||||
Array(Vec<InputValue>),
|
||||
Tuple(Vec<InputValue>),
|
||||
}
|
||||
|
||||
impl TryFrom<(Type, Expression)> for InputValue {
|
||||
@ -38,108 +36,31 @@ impl TryFrom<(Type, Expression)> for InputValue {
|
||||
Ok(match value {
|
||||
(type_, Expression::Value(value)) => {
|
||||
match (type_, value) {
|
||||
(Type::Address, ValueExpression::Address(value, _)) => Self::Address(value.to_string()),
|
||||
(Type::Address, ValueExpression::Address(value, _)) => Self::Address(value),
|
||||
(Type::Boolean, ValueExpression::Boolean(value, span)) => {
|
||||
let bool_value = value.parse::<bool>().map_err(|_| ParserError::unexpected_eof(&span))?; // TODO: change error
|
||||
Self::Boolean(bool_value)
|
||||
}
|
||||
(Type::Char, ValueExpression::Char(value)) => Self::Char(value),
|
||||
(Type::Field, ValueExpression::Field(value, _) | ValueExpression::Implicit(value, _)) => {
|
||||
Self::Field(value.to_string())
|
||||
Self::Field(value)
|
||||
}
|
||||
(Type::Group, ValueExpression::Group(value)) => Self::Group(*value),
|
||||
(Type::IntegerType(type_), ValueExpression::Implicit(value, _)) => {
|
||||
Self::Integer(type_, value.to_string())
|
||||
}
|
||||
(Type::IntegerType(type_), ValueExpression::Implicit(value, _)) => Self::Integer(type_, value),
|
||||
(Type::IntegerType(expected), ValueExpression::Integer(actual, value, span)) => {
|
||||
if expected == actual {
|
||||
Self::Integer(expected, value.to_string())
|
||||
Self::Integer(expected, value)
|
||||
} else {
|
||||
return Err(InputError::unexpected_type(expected.to_string(), actual, &span).into());
|
||||
}
|
||||
}
|
||||
(Type::Array(type_, _), ValueExpression::String(string, span)) => {
|
||||
if !matches!(*type_, Type::Char) {
|
||||
return Err(InputError::string_is_array_of_chars(type_, &span).into());
|
||||
}
|
||||
|
||||
Self::Array(
|
||||
string
|
||||
.into_iter()
|
||||
.map(|c| {
|
||||
Self::Char(CharValue {
|
||||
character: c,
|
||||
span: span.clone(),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
(x, y) => {
|
||||
return Err(InputError::unexpected_type(x, &y, y.span()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
(Type::Array(type_, type_dimensions), Expression::ArrayInit(mut array_init)) => {
|
||||
let span = array_init.span.clone();
|
||||
|
||||
if type_dimensions != array_init.dimensions || array_init.dimensions.is_zero() {
|
||||
return Err(InputError::invalid_array_dimension_size(&span).into());
|
||||
}
|
||||
|
||||
if let Some(dimension) = array_init.dimensions.remove_first() {
|
||||
let size = dimension.value.parse::<usize>().unwrap();
|
||||
let mut values = Vec::with_capacity(size);
|
||||
|
||||
// For when Dimensions are specified in a canonical way: [[u8; 3], 2];
|
||||
// Else treat as math notation: [u8; (2, 3)];
|
||||
if array_init.dimensions.len() == 0 {
|
||||
for _ in 0..size {
|
||||
values.push(InputValue::try_from((*type_.clone(), *array_init.element.clone()))?);
|
||||
}
|
||||
// Faking canonical array init is relatively easy: instead of using a straightforward
|
||||
// recursion, with each iteration we manually modify ArrayInitExpression cutting off
|
||||
// dimension by dimension.
|
||||
} else {
|
||||
for _ in 0..size {
|
||||
values.push(InputValue::try_from((
|
||||
Type::Array(type_.clone(), array_init.dimensions.clone()),
|
||||
Expression::ArrayInit(array_init.clone()),
|
||||
))?);
|
||||
}
|
||||
};
|
||||
|
||||
Self::Array(values)
|
||||
} else {
|
||||
unreachable!("dimensions are checked for zero");
|
||||
}
|
||||
}
|
||||
(Type::Tuple(types), Expression::TupleInit(tuple_init)) => {
|
||||
let size = tuple_init.elements.len();
|
||||
let mut elements = Vec::with_capacity(size);
|
||||
|
||||
if size != types.len() {
|
||||
return Err(InputError::tuple_length_mismatch(size, types.len(), tuple_init.span()).into());
|
||||
}
|
||||
|
||||
for (i, element) in tuple_init.elements.into_iter().enumerate() {
|
||||
elements.push(Self::try_from((types[i].clone(), element))?);
|
||||
}
|
||||
|
||||
Self::Tuple(elements)
|
||||
}
|
||||
(Type::Array(element_type, _dimensions), Expression::ArrayInline(array_inline)) => {
|
||||
let mut elements = Vec::with_capacity(array_inline.elements.len());
|
||||
let span = array_inline.span().clone();
|
||||
|
||||
for element in array_inline.elements.into_iter() {
|
||||
if let SpreadOrExpression::Expression(value_expression) = element {
|
||||
elements.push(Self::try_from((*element_type.clone(), value_expression))?);
|
||||
} else {
|
||||
return Err(InputError::array_spread_is_not_allowed(&span).into());
|
||||
}
|
||||
}
|
||||
Self::Array(elements)
|
||||
(type_, Expression::Unary(unary)) if unary.op == UnaryOperation::Negate => {
|
||||
InputValue::try_from((type_, *unary.inner))?
|
||||
}
|
||||
(_type_, expr) => return Err(InputError::illegal_expression(&expr, expr.span()).into()),
|
||||
})
|
||||
@ -155,14 +76,6 @@ impl fmt::Display for InputValue {
|
||||
InputValue::Group(ref group) => write!(f, "{}", group),
|
||||
InputValue::Field(ref field) => write!(f, "{}", field),
|
||||
InputValue::Integer(ref type_, ref number) => write!(f, "{}{:?}", number, type_),
|
||||
InputValue::Array(ref array) => {
|
||||
let values = array.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ");
|
||||
write!(f, "array [{}]", values)
|
||||
}
|
||||
InputValue::Tuple(ref tuple) => {
|
||||
let values = tuple.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ");
|
||||
write!(f, "({})", values)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,28 +21,22 @@ use super::*;
|
||||
pub struct ProgramInput {
|
||||
pub main: Definitions,
|
||||
pub registers: Definitions,
|
||||
pub constants: Definitions,
|
||||
}
|
||||
|
||||
impl TryFrom<ParsedInputFile> for ProgramInput {
|
||||
impl TryFrom<InputAst> for ProgramInput {
|
||||
type Error = LeoError;
|
||||
fn try_from(input: ParsedInputFile) -> Result<Self> {
|
||||
fn try_from(input: InputAst) -> Result<Self> {
|
||||
let mut main = IndexMap::new();
|
||||
let mut registers = IndexMap::new();
|
||||
let mut constants = IndexMap::new();
|
||||
|
||||
for section in input.sections {
|
||||
let target = match section.name {
|
||||
sym::main => &mut main,
|
||||
sym::registers => &mut registers,
|
||||
sym::constants => &mut constants,
|
||||
_ => {
|
||||
return Err(InputError::unexpected_section(
|
||||
&["main", "registers", "constants"],
|
||||
section.name,
|
||||
§ion.span,
|
||||
return Err(
|
||||
InputError::unexpected_section(&["main", "registers"], section.name, §ion.span).into(),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
};
|
||||
|
||||
@ -54,10 +48,6 @@ impl TryFrom<ParsedInputFile> for ProgramInput {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ProgramInput {
|
||||
main,
|
||||
registers,
|
||||
constants,
|
||||
})
|
||||
Ok(ProgramInput { main, registers })
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ pub struct ProgramState {
|
||||
pub state: Definitions,
|
||||
}
|
||||
|
||||
impl TryFrom<ParsedInputFile> for ProgramState {
|
||||
impl TryFrom<InputAst> for ProgramState {
|
||||
type Error = LeoError;
|
||||
fn try_from(input: ParsedInputFile) -> Result<Self> {
|
||||
fn try_from(input: InputAst) -> Result<Self> {
|
||||
let mut state = IndexMap::new();
|
||||
|
||||
for section in input.sections {
|
||||
|
@ -22,18 +22,6 @@
|
||||
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
pub mod accesses;
|
||||
pub use self::accesses::*;
|
||||
|
||||
pub mod aliases;
|
||||
pub use self::aliases::*;
|
||||
|
||||
pub mod annotation;
|
||||
pub use self::annotation::*;
|
||||
|
||||
pub mod circuits;
|
||||
pub use self::circuits::*;
|
||||
|
||||
pub mod chars;
|
||||
pub use self::chars::*;
|
||||
|
||||
@ -49,21 +37,15 @@ pub use self::functions::*;
|
||||
pub mod groups;
|
||||
pub use self::groups::*;
|
||||
|
||||
pub mod imports;
|
||||
pub use self::imports::*;
|
||||
|
||||
pub mod input;
|
||||
pub use self::input::*;
|
||||
|
||||
pub mod pass;
|
||||
pub use self::pass::*;
|
||||
pub mod passes;
|
||||
pub use self::passes::*;
|
||||
|
||||
pub mod program;
|
||||
pub use self::program::*;
|
||||
|
||||
pub mod reducer;
|
||||
pub use self::reducer::*;
|
||||
|
||||
pub mod statements;
|
||||
pub use self::statements::*;
|
||||
|
||||
@ -162,7 +144,7 @@ impl AsRef<Program> for Ast {
|
||||
}
|
||||
|
||||
/// Helper function to recursively filter keys from AST JSON
|
||||
fn remove_key_from_json(value: serde_json::Value, key: &str) -> serde_json::Value {
|
||||
pub(crate) fn remove_key_from_json(value: serde_json::Value, key: &str) -> serde_json::Value {
|
||||
match value {
|
||||
serde_json::Value::Object(map) => serde_json::Value::Object(
|
||||
map.into_iter()
|
||||
@ -183,7 +165,7 @@ fn remove_key_from_json(value: serde_json::Value, key: &str) -> serde_json::Valu
|
||||
/// 1. Remove empty object mappings from JSON arrays
|
||||
/// 2. If there are two elements in a JSON array and one is an empty object
|
||||
/// mapping and the other is not, then lift up the one that isn't
|
||||
fn normalize_json_value(value: serde_json::Value) -> serde_json::Value {
|
||||
pub(crate) fn normalize_json_value(value: serde_json::Value) -> serde_json::Value {
|
||||
match value {
|
||||
serde_json::Value::Array(vec) => {
|
||||
let orig_length = vec.len();
|
||||
|
@ -14,13 +14,19 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! This module contains both a Director to reconstruct the AST
|
||||
//! which maps over every node of the AST and calls a reducer.
|
||||
//! The Trait for a reducer are methods that can be overridden
|
||||
//! to make changes to how AST nodes are rebuilt.
|
||||
//! This module contains both a Reducer and Visitor design pattern.
|
||||
//! These both iterate over the AST.
|
||||
|
||||
// todo @gluax: Move the files in this module into `leo-passes` in a future PR.
|
||||
|
||||
pub mod reconstructing_reducer;
|
||||
pub use reconstructing_reducer::*;
|
||||
|
||||
pub mod reconstructing_director;
|
||||
pub use reconstructing_director::*;
|
||||
|
||||
pub mod visitor;
|
||||
pub use visitor::*;
|
||||
|
||||
pub mod visitor_director;
|
||||
pub use visitor_director::*;
|
@ -20,7 +20,7 @@
|
||||
use crate::*;
|
||||
|
||||
use leo_errors::{AstError, Result};
|
||||
use leo_span::{Span, Symbol};
|
||||
use leo_span::Span;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
@ -34,21 +34,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
}
|
||||
|
||||
pub fn reduce_type(&mut self, type_: &Type, span: &Span) -> Result<Type> {
|
||||
let new = match type_ {
|
||||
Type::Array(type_, dimensions) => Type::Array(Box::new(self.reduce_type(type_, span)?), dimensions.clone()),
|
||||
Type::Tuple(types) => {
|
||||
let mut reduced_types = vec![];
|
||||
for type_ in types.iter() {
|
||||
reduced_types.push(self.reduce_type(type_, span)?);
|
||||
}
|
||||
|
||||
Type::Tuple(reduced_types)
|
||||
}
|
||||
Type::Identifier(identifier) => Type::Identifier(self.reduce_identifier(identifier)?),
|
||||
_ => type_.clone(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_type(type_, new, span)
|
||||
self.reducer.reduce_type(type_, type_.clone(), span)
|
||||
}
|
||||
|
||||
// Expressions
|
||||
@ -59,16 +45,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
Expression::Binary(binary) => Expression::Binary(self.reduce_binary(binary)?),
|
||||
Expression::Unary(unary) => Expression::Unary(self.reduce_unary(unary)?),
|
||||
Expression::Ternary(ternary) => Expression::Ternary(self.reduce_ternary(ternary)?),
|
||||
Expression::Cast(cast) => Expression::Cast(self.reduce_cast(cast)?),
|
||||
Expression::Access(access) => Expression::Access(self.reduce_access(access)?),
|
||||
|
||||
Expression::ArrayInline(array_inline) => Expression::ArrayInline(self.reduce_array_inline(array_inline)?),
|
||||
Expression::ArrayInit(array_init) => Expression::ArrayInit(self.reduce_array_init(array_init)?),
|
||||
|
||||
Expression::TupleInit(tuple_init) => Expression::TupleInit(self.reduce_tuple_init(tuple_init)?),
|
||||
|
||||
Expression::CircuitInit(circuit_init) => Expression::CircuitInit(self.reduce_circuit_init(circuit_init)?),
|
||||
|
||||
Expression::Call(call) => Expression::Call(self.reduce_call(call)?),
|
||||
Expression::Err(s) => Expression::Err(s.clone()),
|
||||
};
|
||||
@ -130,136 +106,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
self.reducer.reduce_ternary(ternary, condition, if_true, if_false)
|
||||
}
|
||||
|
||||
pub fn reduce_cast(&mut self, cast: &CastExpression) -> Result<CastExpression> {
|
||||
let inner = self.reduce_expression(&cast.inner)?;
|
||||
let target_type = self.reduce_type(&cast.target_type, &cast.span)?;
|
||||
|
||||
self.reducer.reduce_cast(cast, inner, target_type)
|
||||
}
|
||||
|
||||
pub fn reduce_array_access(&mut self, array_access: &ArrayAccess) -> Result<ArrayAccess> {
|
||||
let array = self.reduce_expression(&array_access.array)?;
|
||||
let index = self.reduce_expression(&array_access.index)?;
|
||||
|
||||
self.reducer.reduce_array_access(array_access, array, index)
|
||||
}
|
||||
|
||||
pub fn reduce_array_range_access(&mut self, array_range_access: &ArrayRangeAccess) -> Result<ArrayRangeAccess> {
|
||||
let array = self.reduce_expression(&array_range_access.array)?;
|
||||
let left = array_range_access
|
||||
.left
|
||||
.as_ref()
|
||||
.map(|left| self.reduce_expression(left))
|
||||
.transpose()?;
|
||||
let right = array_range_access
|
||||
.right
|
||||
.as_ref()
|
||||
.map(|right| self.reduce_expression(right))
|
||||
.transpose()?;
|
||||
|
||||
self.reducer
|
||||
.reduce_array_range_access(array_range_access, array, left, right)
|
||||
}
|
||||
|
||||
pub fn reduce_member_access(&mut self, member_access: &MemberAccess) -> Result<MemberAccess> {
|
||||
let inner = self.reduce_expression(&member_access.inner)?;
|
||||
let name = self.reduce_identifier(&member_access.name)?;
|
||||
let type_ = member_access
|
||||
.type_
|
||||
.as_ref()
|
||||
.map(|type_| self.reduce_type(type_, &member_access.span))
|
||||
.transpose()?;
|
||||
|
||||
self.reducer.reduce_member_access(member_access, inner, name, type_)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_access(&mut self, tuple_access: &TupleAccess) -> Result<TupleAccess> {
|
||||
let tuple = self.reduce_expression(&tuple_access.tuple)?;
|
||||
|
||||
self.reducer.reduce_tuple_access(tuple_access, tuple)
|
||||
}
|
||||
|
||||
pub fn reduce_static_access(&mut self, static_access: &StaticAccess) -> Result<StaticAccess> {
|
||||
let value = self.reduce_expression(&static_access.inner)?;
|
||||
let name = self.reduce_identifier(&static_access.name)?;
|
||||
let type_ = self.reduce_type(&static_access.type_.borrow(), &static_access.span)?;
|
||||
|
||||
self.reducer.reduce_static_access(static_access, value, type_, name)
|
||||
}
|
||||
|
||||
pub fn reduce_access(&mut self, access: &AccessExpression) -> Result<AccessExpression> {
|
||||
use AccessExpression::*;
|
||||
|
||||
let new = match access {
|
||||
Array(access) => Array(self.reduce_array_access(access)?),
|
||||
ArrayRange(access) => ArrayRange(self.reduce_array_range_access(access)?),
|
||||
Member(access) => Member(self.reduce_member_access(access)?),
|
||||
Tuple(access) => Tuple(self.reduce_tuple_access(access)?),
|
||||
Static(access) => Static(self.reduce_static_access(access)?),
|
||||
};
|
||||
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
pub fn reduce_array_inline(&mut self, array_inline: &ArrayInlineExpression) -> Result<ArrayInlineExpression> {
|
||||
let mut elements = vec![];
|
||||
for element in array_inline.elements.iter() {
|
||||
let reduced_element = match element {
|
||||
SpreadOrExpression::Expression(expression) => {
|
||||
SpreadOrExpression::Expression(self.reduce_expression(expression)?)
|
||||
}
|
||||
SpreadOrExpression::Spread(expression) => {
|
||||
SpreadOrExpression::Spread(self.reduce_expression(expression)?)
|
||||
}
|
||||
};
|
||||
|
||||
elements.push(reduced_element);
|
||||
}
|
||||
|
||||
self.reducer.reduce_array_inline(array_inline, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_array_init(&mut self, array_init: &ArrayInitExpression) -> Result<ArrayInitExpression> {
|
||||
let element = self.reduce_expression(&array_init.element)?;
|
||||
|
||||
self.reducer.reduce_array_init(array_init, element)
|
||||
}
|
||||
|
||||
pub fn reduce_tuple_init(&mut self, tuple_init: &TupleInitExpression) -> Result<TupleInitExpression> {
|
||||
let mut elements = vec![];
|
||||
for element in tuple_init.elements.iter() {
|
||||
elements.push(self.reduce_expression(element)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_tuple_init(tuple_init, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_variable_initializer(
|
||||
&mut self,
|
||||
variable: &CircuitVariableInitializer,
|
||||
) -> Result<CircuitVariableInitializer> {
|
||||
let identifier = self.reduce_identifier(&variable.identifier)?;
|
||||
let expression = variable
|
||||
.expression
|
||||
.as_ref()
|
||||
.map(|expr| self.reduce_expression(expr))
|
||||
.transpose()?;
|
||||
|
||||
self.reducer
|
||||
.reduce_circuit_variable_initializer(variable, identifier, expression)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_init(&mut self, circuit_init: &CircuitInitExpression) -> Result<CircuitInitExpression> {
|
||||
let name = self.reduce_identifier(&circuit_init.name)?;
|
||||
|
||||
let mut members = vec![];
|
||||
for member in circuit_init.members.iter() {
|
||||
members.push(self.reduce_circuit_variable_initializer(member)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_circuit_init(circuit_init, name, members)
|
||||
}
|
||||
|
||||
pub fn reduce_call(&mut self, call: &CallExpression) -> Result<CallExpression> {
|
||||
let function = self.reduce_expression(&call.function)?;
|
||||
|
||||
@ -416,57 +262,12 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
inputs.push(self.reduce_function_input(input)?);
|
||||
}
|
||||
|
||||
let mut import_statements = vec![];
|
||||
for import in program.import_statements.iter() {
|
||||
import_statements.push(self.reduce_import_statement(import)?);
|
||||
}
|
||||
|
||||
let mut imports = IndexMap::new();
|
||||
for (identifier, program) in program.imports.iter() {
|
||||
let (ident, import) = self.reduce_import(identifier, program)?;
|
||||
imports.insert(ident, import);
|
||||
}
|
||||
|
||||
let mut aliases = IndexMap::new();
|
||||
for (name, alias) in program.aliases.iter() {
|
||||
let represents = self.reduce_type(&alias.represents, &alias.name.span)?;
|
||||
aliases.insert(
|
||||
name.clone(),
|
||||
Alias {
|
||||
name: alias.name.clone(),
|
||||
span: alias.span.clone(),
|
||||
represents,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let mut circuits = IndexMap::new();
|
||||
self.reducer.swap_in_circuit();
|
||||
for (name, circuit) in program.circuits.iter() {
|
||||
circuits.insert(name.clone(), self.reduce_circuit(circuit)?);
|
||||
}
|
||||
self.reducer.swap_in_circuit();
|
||||
|
||||
let mut functions = IndexMap::new();
|
||||
for (name, function) in program.functions.iter() {
|
||||
functions.insert(name.clone(), self.reduce_function(function)?);
|
||||
}
|
||||
|
||||
let mut global_consts = IndexMap::new();
|
||||
for (name, definition) in program.global_consts.iter() {
|
||||
global_consts.insert(name.clone(), self.reduce_definition(definition)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_program(
|
||||
program,
|
||||
inputs,
|
||||
import_statements,
|
||||
imports,
|
||||
aliases,
|
||||
circuits,
|
||||
functions,
|
||||
global_consts,
|
||||
)
|
||||
self.reducer.reduce_program(program, inputs, functions)
|
||||
}
|
||||
|
||||
pub fn reduce_function_input_variable(
|
||||
@ -474,7 +275,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
variable: &FunctionInputVariable,
|
||||
) -> Result<FunctionInputVariable> {
|
||||
let identifier = self.reduce_identifier(&variable.identifier)?;
|
||||
let type_ = self.reduce_type(&variable.type_, &variable.span)?;
|
||||
let type_ = self.reduce_type(&variable.type_(), &variable.span)?;
|
||||
|
||||
self.reducer.reduce_function_input_variable(variable, identifier, type_)
|
||||
}
|
||||
@ -484,91 +285,14 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
FunctionInput::Variable(function_input_variable) => {
|
||||
FunctionInput::Variable(self.reduce_function_input_variable(function_input_variable)?)
|
||||
}
|
||||
_ => input.clone(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_function_input(input, new)
|
||||
}
|
||||
|
||||
pub fn reduce_import_tree(&mut self, tree: &ImportTree) -> Result<ImportTree> {
|
||||
let new = ImportTree {
|
||||
base: tree
|
||||
.base
|
||||
.iter()
|
||||
.map(|i| self.reduce_identifier(i))
|
||||
.collect::<Result<_>>()?,
|
||||
|
||||
kind: match &tree.kind {
|
||||
ImportTreeKind::Glob { .. } | ImportTreeKind::Leaf { alias: None } => tree.kind.clone(),
|
||||
ImportTreeKind::Leaf { alias: Some(alias) } => {
|
||||
let alias = self.reduce_identifier(alias)?;
|
||||
ImportTreeKind::Leaf { alias: Some(alias) }
|
||||
}
|
||||
ImportTreeKind::Nested { tree } => ImportTreeKind::Nested {
|
||||
tree: tree.iter().map(|n| self.reduce_import_tree(n)).collect::<Result<_>>()?,
|
||||
},
|
||||
},
|
||||
span: tree.span.clone(),
|
||||
};
|
||||
|
||||
self.reducer.reduce_import_tree(tree, new)
|
||||
}
|
||||
|
||||
pub fn reduce_import_statement(&mut self, import: &ImportStatement) -> Result<ImportStatement> {
|
||||
let tree = self.reduce_import_tree(&import.tree)?;
|
||||
self.reducer.reduce_import_statement(import, tree)
|
||||
}
|
||||
|
||||
pub fn reduce_import(&mut self, identifier: &[Symbol], import: &Program) -> Result<(Vec<Symbol>, Program)> {
|
||||
let new_identifer = identifier.to_vec();
|
||||
let new_import = self.reduce_program(import)?;
|
||||
self.reducer.reduce_import(new_identifer, new_import)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_member(&mut self, circuit_member: &CircuitMember) -> Result<CircuitMember> {
|
||||
let new = match circuit_member {
|
||||
CircuitMember::CircuitConst(identifier, type_, value) => CircuitMember::CircuitConst(
|
||||
self.reduce_identifier(identifier)?,
|
||||
self.reduce_type(type_, &identifier.span)?,
|
||||
self.reduce_expression(value)?,
|
||||
),
|
||||
CircuitMember::CircuitVariable(identifier, type_) => CircuitMember::CircuitVariable(
|
||||
self.reduce_identifier(identifier)?,
|
||||
self.reduce_type(type_, &identifier.span)?,
|
||||
),
|
||||
CircuitMember::CircuitFunction(function) => {
|
||||
CircuitMember::CircuitFunction(Box::new(self.reduce_function(function)?))
|
||||
}
|
||||
};
|
||||
|
||||
self.reducer.reduce_circuit_member(circuit_member, new)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit(&mut self, circuit: &Circuit) -> Result<Circuit> {
|
||||
let circuit_name = self.reduce_identifier(&circuit.circuit_name)?;
|
||||
|
||||
let mut members = vec![];
|
||||
for member in circuit.members.iter() {
|
||||
members.push(self.reduce_circuit_member(member)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_circuit(circuit, circuit_name, members)
|
||||
}
|
||||
|
||||
fn reduce_annotation(&mut self, annotation: &Annotation) -> Result<Annotation> {
|
||||
let name = self.reduce_identifier(&annotation.name)?;
|
||||
|
||||
self.reducer.reduce_annotation(annotation, name)
|
||||
}
|
||||
|
||||
pub fn reduce_function(&mut self, function: &Function) -> Result<Function> {
|
||||
let identifier = self.reduce_identifier(&function.identifier)?;
|
||||
|
||||
let mut annotations = IndexMap::new();
|
||||
for (name, annotation) in function.annotations.iter() {
|
||||
annotations.insert(*name, self.reduce_annotation(annotation)?);
|
||||
}
|
||||
|
||||
let mut inputs = vec![];
|
||||
for input in function.input.iter() {
|
||||
inputs.push(self.reduce_function_input(input)?);
|
||||
@ -578,14 +302,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
|
||||
let block = self.reduce_block(&function.block)?;
|
||||
|
||||
self.reducer.reduce_function(
|
||||
function,
|
||||
identifier,
|
||||
annotations,
|
||||
inputs,
|
||||
function.const_,
|
||||
output,
|
||||
block,
|
||||
)
|
||||
self.reducer
|
||||
.reduce_function(function, identifier, inputs, function.const_, output, block)
|
||||
}
|
||||
}
|
@ -18,8 +18,6 @@
|
||||
//! It implements default methods for each node to be made
|
||||
//! given the information of the old node.
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::*;
|
||||
|
||||
use leo_errors::Result;
|
||||
@ -115,136 +113,6 @@ pub trait ReconstructingReducer {
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_cast(&mut self, cast: &CastExpression, inner: Expression, target_type: Type) -> Result<CastExpression> {
|
||||
Ok(CastExpression {
|
||||
inner: Box::new(inner),
|
||||
target_type,
|
||||
span: cast.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_access(
|
||||
&mut self,
|
||||
array_access: &ArrayAccess,
|
||||
array: Expression,
|
||||
index: Expression,
|
||||
) -> Result<ArrayAccess> {
|
||||
Ok(ArrayAccess {
|
||||
array: Box::new(array),
|
||||
index: Box::new(index),
|
||||
span: array_access.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_range_access(
|
||||
&mut self,
|
||||
array_rage_access: &ArrayRangeAccess,
|
||||
array: Expression,
|
||||
left: Option<Expression>,
|
||||
right: Option<Expression>,
|
||||
) -> Result<ArrayRangeAccess> {
|
||||
Ok(ArrayRangeAccess {
|
||||
array: Box::new(array),
|
||||
left: left.map(|expr| Box::new(expr)),
|
||||
right: right.map(|expr| Box::new(expr)),
|
||||
span: array_rage_access.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_member_access(
|
||||
&mut self,
|
||||
member_access: &MemberAccess,
|
||||
inner: Expression,
|
||||
name: Identifier,
|
||||
type_: Option<Type>,
|
||||
) -> Result<MemberAccess> {
|
||||
Ok(MemberAccess {
|
||||
inner: Box::new(inner),
|
||||
name,
|
||||
span: member_access.span.clone(),
|
||||
type_,
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_tuple_access(&mut self, tuple_access: &TupleAccess, tuple: Expression) -> Result<TupleAccess> {
|
||||
Ok(TupleAccess {
|
||||
tuple: Box::new(tuple),
|
||||
index: tuple_access.index.clone(),
|
||||
span: tuple_access.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_static_access(
|
||||
&mut self,
|
||||
static_access: &StaticAccess,
|
||||
value: Expression,
|
||||
type_: Type,
|
||||
name: Identifier,
|
||||
) -> Result<StaticAccess> {
|
||||
Ok(StaticAccess {
|
||||
inner: Box::new(value),
|
||||
name,
|
||||
type_: RefCell::new(type_),
|
||||
span: static_access.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_inline(
|
||||
&mut self,
|
||||
array_inline: &ArrayInlineExpression,
|
||||
elements: Vec<SpreadOrExpression>,
|
||||
) -> Result<ArrayInlineExpression> {
|
||||
Ok(ArrayInlineExpression {
|
||||
elements,
|
||||
span: array_inline.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_array_init(
|
||||
&mut self,
|
||||
array_init: &ArrayInitExpression,
|
||||
element: Expression,
|
||||
) -> Result<ArrayInitExpression> {
|
||||
Ok(ArrayInitExpression {
|
||||
element: Box::new(element),
|
||||
dimensions: array_init.dimensions.clone(),
|
||||
span: array_init.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_tuple_init(
|
||||
&mut self,
|
||||
tuple_init: &TupleInitExpression,
|
||||
elements: Vec<Expression>,
|
||||
) -> Result<TupleInitExpression> {
|
||||
Ok(TupleInitExpression {
|
||||
elements,
|
||||
span: tuple_init.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_circuit_variable_initializer(
|
||||
&mut self,
|
||||
_variable: &CircuitVariableInitializer,
|
||||
identifier: Identifier,
|
||||
expression: Option<Expression>,
|
||||
) -> Result<CircuitVariableInitializer> {
|
||||
Ok(CircuitVariableInitializer { identifier, expression })
|
||||
}
|
||||
|
||||
fn reduce_circuit_init(
|
||||
&mut self,
|
||||
circuit_init: &CircuitInitExpression,
|
||||
name: Identifier,
|
||||
members: Vec<CircuitVariableInitializer>,
|
||||
) -> Result<CircuitInitExpression> {
|
||||
Ok(CircuitInitExpression {
|
||||
name,
|
||||
members,
|
||||
span: circuit_init.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_call(
|
||||
&mut self,
|
||||
call: &CallExpression,
|
||||
@ -286,9 +154,8 @@ pub trait ReconstructingReducer {
|
||||
value: Expression,
|
||||
) -> Result<DefinitionStatement> {
|
||||
Ok(DefinitionStatement {
|
||||
declaration_type: definition.declaration_type.clone(),
|
||||
declaration_type: definition.declaration_type,
|
||||
variable_names,
|
||||
parened: definition.parened,
|
||||
type_,
|
||||
value,
|
||||
span: definition.span.clone(),
|
||||
@ -392,22 +259,12 @@ pub trait ReconstructingReducer {
|
||||
&mut self,
|
||||
program: &Program,
|
||||
expected_input: Vec<FunctionInput>,
|
||||
import_statements: Vec<ImportStatement>,
|
||||
imports: IndexMap<Vec<Symbol>, Program>,
|
||||
aliases: IndexMap<Identifier, Alias>,
|
||||
circuits: IndexMap<Identifier, Circuit>,
|
||||
functions: IndexMap<Identifier, Function>,
|
||||
global_consts: IndexMap<Vec<Identifier>, DefinitionStatement>,
|
||||
) -> Result<Program> {
|
||||
Ok(Program {
|
||||
name: program.name.clone(),
|
||||
expected_input,
|
||||
import_statements,
|
||||
imports,
|
||||
aliases,
|
||||
circuits,
|
||||
functions,
|
||||
global_consts,
|
||||
})
|
||||
}
|
||||
|
||||
@ -417,61 +274,27 @@ pub trait ReconstructingReducer {
|
||||
identifier: Identifier,
|
||||
type_: Type,
|
||||
) -> Result<FunctionInputVariable> {
|
||||
Ok(FunctionInputVariable {
|
||||
Ok(FunctionInputVariable::new(
|
||||
identifier,
|
||||
const_: variable.const_,
|
||||
mutable: variable.mutable,
|
||||
variable.mode(),
|
||||
type_,
|
||||
span: variable.span.clone(),
|
||||
})
|
||||
variable.span.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
fn reduce_function_input(&mut self, _input: &FunctionInput, new: FunctionInput) -> Result<FunctionInput> {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
fn reduce_import_tree(&mut self, _tree: &ImportTree, new: ImportTree) -> Result<ImportTree> {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
fn reduce_import_statement(&mut self, import: &ImportStatement, tree: ImportTree) -> Result<ImportStatement> {
|
||||
Ok(ImportStatement {
|
||||
tree,
|
||||
span: import.span.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_import(&mut self, identifier: Vec<Symbol>, import: Program) -> Result<(Vec<Symbol>, Program)> {
|
||||
Ok((identifier, import))
|
||||
}
|
||||
|
||||
fn reduce_circuit_member(&mut self, _circuit_member: &CircuitMember, new: CircuitMember) -> Result<CircuitMember> {
|
||||
Ok(new)
|
||||
}
|
||||
|
||||
fn reduce_circuit(
|
||||
&mut self,
|
||||
_circuit: &Circuit,
|
||||
circuit_name: Identifier,
|
||||
members: Vec<CircuitMember>,
|
||||
) -> Result<Circuit> {
|
||||
Ok(Circuit { circuit_name, members })
|
||||
}
|
||||
|
||||
fn reduce_annotation(&mut self, annotation: &Annotation, name: Identifier) -> Result<Annotation> {
|
||||
Ok(Annotation {
|
||||
span: annotation.span.clone(),
|
||||
name,
|
||||
arguments: annotation.arguments.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn reduce_function(
|
||||
&mut self,
|
||||
function: &Function,
|
||||
identifier: Identifier,
|
||||
annotations: IndexMap<Symbol, Annotation>,
|
||||
input: Vec<FunctionInput>,
|
||||
const_: bool,
|
||||
output: Type,
|
||||
@ -479,7 +302,6 @@ pub trait ReconstructingReducer {
|
||||
) -> Result<Function> {
|
||||
Ok(Function {
|
||||
identifier,
|
||||
annotations,
|
||||
input,
|
||||
const_,
|
||||
output,
|
112
compiler/ast/src/passes/visitor.rs
Normal file
112
compiler/ast/src/passes/visitor.rs
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! This module contains Visitor traits for the AST.
|
||||
|
||||
use crate::*;
|
||||
|
||||
pub enum VisitResult {
|
||||
VisitChildren,
|
||||
SkipChildren,
|
||||
}
|
||||
|
||||
impl Default for VisitResult {
|
||||
fn default() -> Self {
|
||||
VisitResult::VisitChildren
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ExpressionVisitor<'a> {
|
||||
fn visit_expression(&mut self, _input: &'a Expression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_identifier(&mut self, _input: &'a Identifier) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_value(&mut self, _input: &'a ValueExpression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_binary(&mut self, _input: &'a BinaryExpression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_unary(&mut self, _input: &'a UnaryExpression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_ternary(&mut self, _input: &'a TernaryExpression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_call(&mut self, _input: &'a CallExpression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_err(&mut self, _input: &'a ErrExpression) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait StatementVisitor<'a> {
|
||||
fn visit_statement(&mut self, _input: &'a Statement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_return(&mut self, _input: &'a ReturnStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, _input: &'a DefinitionStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_assign(&mut self, _input: &'a AssignStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_conditional(&mut self, _input: &'a ConditionalStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_iteration(&mut self, _input: &'a IterationStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_console(&mut self, _input: &'a ConsoleStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_expression_statement(&mut self, _input: &'a ExpressionStatement) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, _input: &'a Block) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ProgramVisitor<'a> {
|
||||
fn visit_program(&mut self, _input: &'a Program) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, _input: &'a Function) -> VisitResult {
|
||||
Default::default()
|
||||
}
|
||||
}
|
176
compiler/ast/src/passes/visitor_director.rs
Normal file
176
compiler/ast/src/passes/visitor_director.rs
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! This module contains Visitor trait implementations for the AST.
|
||||
//! It implements default methods for each node to be made
|
||||
//! given the type of node its visiting.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::*;
|
||||
|
||||
pub struct VisitorDirector<'a, V: ExpressionVisitor<'a>> {
|
||||
visitor: V,
|
||||
lifetime: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a, V: ExpressionVisitor<'a>> VisitorDirector<'a, V> {
|
||||
pub fn new(visitor: V) -> Self {
|
||||
Self {
|
||||
visitor,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visitor(self) -> V {
|
||||
self.visitor
|
||||
}
|
||||
|
||||
pub fn visit_expression(&mut self, input: &'a Expression) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_expression(input) {
|
||||
match input {
|
||||
Expression::Identifier(_) => {}
|
||||
Expression::Value(_) => {}
|
||||
Expression::Binary(expr) => self.visit_binary(expr),
|
||||
Expression::Unary(expr) => self.visit_unary(expr),
|
||||
Expression::Ternary(expr) => self.visit_ternary(expr),
|
||||
Expression::Call(expr) => self.visit_call(expr),
|
||||
Expression::Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_binary(&mut self, input: &'a BinaryExpression) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_binary(input) {
|
||||
self.visit_expression(&input.left);
|
||||
self.visit_expression(&input.right);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_unary(&mut self, input: &'a UnaryExpression) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_unary(input) {
|
||||
self.visit_expression(&input.inner);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_ternary(&mut self, input: &'a TernaryExpression) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_ternary(input) {
|
||||
self.visit_expression(&input.condition);
|
||||
self.visit_expression(&input.if_true);
|
||||
self.visit_expression(&input.if_false);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_call(&mut self, input: &'a CallExpression) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_call(input) {
|
||||
self.visit_expression(&input.function);
|
||||
for expr in input.arguments.iter() {
|
||||
self.visit_expression(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: ExpressionVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V> {
|
||||
pub fn visit_statement(&mut self, input: &'a Statement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_statement(input) {
|
||||
match input {
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Assign(stmt) => self.visit_assign(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_return(&mut self, input: &'a ReturnStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_return(input) {
|
||||
self.visit_expression(&input.expression);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_definition(input) {
|
||||
self.visit_expression(&input.value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_assign(&mut self, input: &'a AssignStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_assign(input) {
|
||||
self.visit_expression(&input.value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_conditional(&mut self, input: &'a ConditionalStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_conditional(input) {
|
||||
self.visit_expression(&input.condition);
|
||||
self.visit_block(&input.block);
|
||||
if let Some(stmt) = input.next.as_ref() {
|
||||
self.visit_statement(stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_iteration(&mut self, input: &'a IterationStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_iteration(input) {
|
||||
self.visit_expression(&input.start);
|
||||
self.visit_expression(&input.stop);
|
||||
self.visit_block(&input.block);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_console(input) {
|
||||
if let ConsoleFunction::Assert(expr) = &input.function {
|
||||
self.visit_expression(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_expression_statement(input) {
|
||||
self.visit_expression(&input.expression);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_block(&mut self, input: &'a Block) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_block(input) {
|
||||
for stmt in input.statements.iter() {
|
||||
self.visit_statement(stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: ExpressionVisitor<'a> + ProgramVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V> {
|
||||
pub fn visit_program(&mut self, input: &'a Program) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_program(input) {
|
||||
for function in input.functions.values() {
|
||||
self.visit_function(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_function(&mut self, input: &'a Function) {
|
||||
if let VisitResult::VisitChildren = self.visitor.visit_function(input) {
|
||||
self.visit_block(&input.block);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,9 +17,7 @@
|
||||
//! A Leo program consists of import, circuit, and function definitions.
|
||||
//! Each defined type consists of ast statements and expressions.
|
||||
|
||||
use crate::{Alias, Circuit, CircuitMember, DefinitionStatement, Function, FunctionInput, Identifier, ImportStatement};
|
||||
|
||||
use leo_span::{sym, Symbol};
|
||||
use crate::{Function, FunctionInput, Identifier};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -34,18 +32,6 @@ pub struct Program {
|
||||
/// Expected main function inputs.
|
||||
/// Empty after parsing.
|
||||
pub expected_input: Vec<FunctionInput>,
|
||||
/// The collected import statements.
|
||||
pub import_statements: Vec<ImportStatement>,
|
||||
#[serde(with = "crate::common::imported_modules")]
|
||||
/// A map from paths to injected programs.
|
||||
pub imports: IndexMap<Vec<Symbol>, Program>,
|
||||
/// A map from alias names to type aliases.
|
||||
pub aliases: IndexMap<Identifier, Alias>,
|
||||
/// A map from circuit names to circuit definitions.
|
||||
pub circuits: IndexMap<Identifier, Circuit>,
|
||||
/// A map from constant names to their definitions.
|
||||
#[serde(with = "crate::common::global_consts_json")]
|
||||
pub global_consts: IndexMap<Vec<Identifier>, DefinitionStatement>,
|
||||
/// A map from function names to their definitions.
|
||||
pub functions: IndexMap<Identifier, Function>,
|
||||
}
|
||||
@ -58,26 +44,6 @@ impl AsRef<Program> for Program {
|
||||
|
||||
impl fmt::Display for Program {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for import in self.import_statements.iter() {
|
||||
import.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
}
|
||||
writeln!(f,)?;
|
||||
for (_, alias) in self.aliases.iter() {
|
||||
alias.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
}
|
||||
writeln!(f,)?;
|
||||
for (_, import) in self.imports.iter() {
|
||||
import.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
}
|
||||
writeln!(f,)?;
|
||||
for (_, circuit) in self.circuits.iter() {
|
||||
circuit.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
}
|
||||
writeln!(f,)?;
|
||||
for (_, function) in self.functions.iter() {
|
||||
function.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
@ -92,47 +58,10 @@ impl Program {
|
||||
Self {
|
||||
name,
|
||||
expected_input: vec![],
|
||||
import_statements: vec![],
|
||||
imports: IndexMap::new(),
|
||||
aliases: IndexMap::new(),
|
||||
circuits: IndexMap::new(),
|
||||
global_consts: IndexMap::new(),
|
||||
functions: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles all internal annotations like `@CoreFunction` and `@AlwaysConst`.
|
||||
pub fn handle_internal_annotations(&mut self) {
|
||||
self.circuits
|
||||
.iter_mut()
|
||||
.flat_map(|(_, circuit)| &mut circuit.members)
|
||||
.filter_map(|member| {
|
||||
if let CircuitMember::CircuitFunction(function) = member {
|
||||
Some(function)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.for_each(|function| {
|
||||
function.annotations.retain(|name, core_map| {
|
||||
match *name {
|
||||
sym::CoreFunction => {
|
||||
let new = core_map.arguments.get(0).copied().or(Some(function.identifier.name));
|
||||
function.core_mapping.replace(new);
|
||||
false
|
||||
}
|
||||
sym::AlwaysConst => {
|
||||
function.const_ = true;
|
||||
false
|
||||
}
|
||||
// Could still be a valid annotation.
|
||||
// Carry on and let ASG handle.
|
||||
_ => true,
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/// Extract the name of the program.
|
||||
pub fn get_name(&self) -> String {
|
||||
self.name.to_string()
|
||||
|
@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// The sort of bindings to introduce, either `let` or `const`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Declare {
|
||||
/// This is a `const` binding.
|
||||
Const,
|
||||
|
@ -33,8 +33,6 @@ pub struct DefinitionStatement {
|
||||
pub declaration_type: Declare,
|
||||
/// The bindings / variable names to declare.
|
||||
pub variable_names: Vec<VariableName>,
|
||||
/// Tracks whether the variable(s) are in parens.
|
||||
pub parened: bool,
|
||||
/// The types of the bindings, if specified, or inferred otherwise.
|
||||
pub type_: Type,
|
||||
/// An initializer value for the bindings.
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{ArrayDimensions, Identifier, IntegerType};
|
||||
use crate::IntegerType;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
@ -36,39 +36,12 @@ pub enum Type {
|
||||
/// An integer type.
|
||||
IntegerType(IntegerType),
|
||||
|
||||
// Data type wrappers
|
||||
/// An array type `[element; dimensions]`.
|
||||
Array(Box<Type>, ArrayDimensions),
|
||||
|
||||
/// A tuple type `(T_0, T_1, ...)` made up of a list of types.
|
||||
Tuple(Vec<Type>),
|
||||
|
||||
/// A reference to either a nominal type (e.g., a `circuit`) or a type alias.
|
||||
Identifier(Identifier),
|
||||
|
||||
/// The `Self` type, allowed within `circuit` definitions.
|
||||
SelfType,
|
||||
|
||||
/// Placeholder for a type that could not be resolved or was not well-formed.
|
||||
/// Will eventually lead to a compile error.
|
||||
Err,
|
||||
}
|
||||
|
||||
impl Type {
|
||||
///
|
||||
/// Returns `true` if the self `Type` is the `SelfType`.
|
||||
///
|
||||
pub fn is_self(&self) -> bool {
|
||||
matches!(self, Type::SelfType)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the self `Type` is a `Circuit`.
|
||||
///
|
||||
pub fn is_circuit(&self) -> bool {
|
||||
matches!(self, Type::Identifier(_))
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns `true` if the self `Type` is equal to the other `Type`.
|
||||
///
|
||||
@ -82,33 +55,6 @@ impl Type {
|
||||
(Type::Field, Type::Field) => true,
|
||||
(Type::Group, Type::Group) => true,
|
||||
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
|
||||
(Type::Identifier(left), Type::Identifier(right)) => left.eq(right),
|
||||
(Type::SelfType, Type::SelfType) => true,
|
||||
(Type::Array(left_type, left_dims), Type::Array(right_type, right_dims)) => {
|
||||
// Convert array dimensions to owned.
|
||||
let mut left_dims = left_dims.to_owned();
|
||||
let mut right_dims = right_dims.to_owned();
|
||||
|
||||
// Remove the first element from both dimensions.
|
||||
let left_first = left_dims.remove_first();
|
||||
let right_first = right_dims.remove_first();
|
||||
|
||||
// Compare the first dimensions.
|
||||
if left_first.ne(&right_first) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a new array type from the remaining array dimensions.
|
||||
let left_new_type = inner_array_type(*left_type.to_owned(), left_dims);
|
||||
let right_new_type = inner_array_type(*right_type.to_owned(), right_dims);
|
||||
|
||||
// Call eq_flat() on the new left and right types.
|
||||
left_new_type.eq_flat(&right_new_type)
|
||||
}
|
||||
(Type::Tuple(left), Type::Tuple(right)) => left
|
||||
.iter()
|
||||
.zip(right)
|
||||
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -123,33 +69,7 @@ impl fmt::Display for Type {
|
||||
Type::Field => write!(f, "field"),
|
||||
Type::Group => write!(f, "group"),
|
||||
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
|
||||
Type::Identifier(ref variable) => write!(f, "circuit {}", variable),
|
||||
Type::SelfType => write!(f, "SelfType"),
|
||||
Type::Array(ref array, ref dimensions) => write!(f, "[{}; {}]", *array, dimensions),
|
||||
Type::Tuple(ref tuple) => {
|
||||
let types = tuple.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ");
|
||||
|
||||
write!(f, "({})", types)
|
||||
}
|
||||
Type::Err => write!(f, "error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the type of the inner array given an array element and array dimensions.
|
||||
///
|
||||
/// If the array has no dimensions, then an inner array does not exist. Simply return the given
|
||||
/// element type.
|
||||
///
|
||||
/// If the array has dimensions, then an inner array exists. Create a new type for the
|
||||
/// inner array. The element type of the new array should be the same as the old array. The
|
||||
/// dimensions of the new array should be the old array dimensions with the first dimension removed.
|
||||
pub fn inner_array_type(element_type: Type, dimensions: ArrayDimensions) -> Type {
|
||||
if dimensions.is_empty() {
|
||||
// The array has one dimension.
|
||||
element_type
|
||||
} else {
|
||||
// The array has multiple dimensions.
|
||||
Type::Array(Box::new(element_type), dimensions)
|
||||
}
|
||||
}
|
||||
|
@ -22,24 +22,36 @@ rust-version = "1.56.1"
|
||||
path = "../ast"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-ast-passes]
|
||||
path = "../ast-passes"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-errors]
|
||||
path = "../../leo/errors"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-passes]
|
||||
path = "../passes"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-parser]
|
||||
path = "../parser"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.leo-span]
|
||||
[dependencies.sha2]
|
||||
version = "0.10"
|
||||
|
||||
[dev-dependencies.leo-span]
|
||||
path = "../../leo/span"
|
||||
version = "1.5.3"
|
||||
|
||||
[dependencies.sha2]
|
||||
version = "0.10"
|
||||
[dev-dependencies.leo-test-framework]
|
||||
path = "../../tests/test-framework"
|
||||
version = "1.4.0"
|
||||
|
||||
[dev-dependencies.serde]
|
||||
version = "1.0.136"
|
||||
features = ["derive"]
|
||||
|
||||
[dev-dependencies.serde_yaml]
|
||||
version = "0.8.23"
|
||||
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
|
@ -22,21 +22,28 @@
|
||||
#![allow(clippy::upper_case_acronyms)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
pub use leo_ast::Ast;
|
||||
use leo_ast::AstPass;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
use leo_ast::Program;
|
||||
pub use leo_ast::{Ast, InputAst};
|
||||
use leo_errors::emitter::Handler;
|
||||
use leo_errors::{CompilerError, Result};
|
||||
use leo_span::symbol::create_session_if_not_set_then;
|
||||
pub use leo_passes::SymbolTable;
|
||||
use leo_passes::*;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone)]
|
||||
/// The primary entry point of the Leo compiler.
|
||||
pub struct Compiler<'a> {
|
||||
handler: &'a Handler,
|
||||
main_file_path: PathBuf,
|
||||
output_directory: PathBuf,
|
||||
pub ast: Ast,
|
||||
pub input_ast: Option<InputAst>,
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
@ -48,6 +55,8 @@ impl<'a> Compiler<'a> {
|
||||
handler,
|
||||
main_file_path,
|
||||
output_directory,
|
||||
ast: Ast::new(Program::new("Initial".to_string())),
|
||||
input_ast: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,16 +76,10 @@ impl<'a> Compiler<'a> {
|
||||
Ok(format!("{:x}", hash))
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs the compiler stages.
|
||||
///
|
||||
fn compiler_stages(self) -> Result<leo_ast::Ast> {
|
||||
// Load the program file.
|
||||
let program_string = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e))?;
|
||||
|
||||
// Parses and stores a program file content from a string, constructs a syntax tree, and generates a program.
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str) -> Result<()> {
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
let mut ast: leo_ast::Ast = leo_parser::parse_ast(
|
||||
let ast: leo_ast::Ast = leo_parser::parse_ast(
|
||||
self.handler,
|
||||
self.main_file_path.to_str().unwrap_or_default(),
|
||||
program_string,
|
||||
@ -84,18 +87,56 @@ impl<'a> Compiler<'a> {
|
||||
// Write the AST snapshot post parsing.
|
||||
ast.to_json_file_without_keys(self.output_directory.clone(), "initial_ast.json", &["span"])?;
|
||||
|
||||
// Canonicalize the AST.
|
||||
ast = leo_ast_passes::Canonicalizer::do_pass(Default::default(), ast.into_repr())?;
|
||||
// Write the AST snapshot post parsing
|
||||
ast.to_json_file_without_keys(self.output_directory, "canonicalization_ast.json", &["span"])?;
|
||||
self.ast = ast;
|
||||
|
||||
Ok(ast)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses and stores the main program file, constructs a syntax tree, and generates a program.
|
||||
pub fn parse_program(&mut self) -> Result<()> {
|
||||
// Load the program file.
|
||||
let program_string = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e))?;
|
||||
|
||||
self.parse_program_from_string(&program_string)
|
||||
}
|
||||
|
||||
/// Parses and stores the input file, constructs a syntax tree, and generates a program input.
|
||||
pub fn parse_input_from_string(&mut self, input_file_path: PathBuf, input_string: &str) -> Result<()> {
|
||||
let input_ast =
|
||||
leo_parser::parse_input(self.handler, input_file_path.to_str().unwrap_or_default(), input_string)?;
|
||||
input_ast.to_json_file_without_keys(self.output_directory.clone(), "inital_input_ast.json", &["span"])?;
|
||||
|
||||
self.input_ast = Some(input_ast);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses and stores the input file, constructs a syntax tree, and generates a program input.
|
||||
pub fn parse_input(&mut self, input_file_path: PathBuf) -> Result<()> {
|
||||
// Load the input file if it exists.
|
||||
if input_file_path.exists() {
|
||||
let input_string = fs::read_to_string(&input_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(input_file_path.clone(), e))?;
|
||||
|
||||
self.parse_input_from_string(input_file_path, &input_string)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs the compiler stages.
|
||||
///
|
||||
fn compiler_stages(&self) -> Result<SymbolTable<'_>> {
|
||||
let symbol_table = CreateSymbolTable::do_pass((&self.ast, self.handler))?;
|
||||
|
||||
Ok(symbol_table)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a compiled Leo program.
|
||||
///
|
||||
pub fn compile(self) -> Result<leo_ast::Ast> {
|
||||
create_session_if_not_set_then(|_| self.compiler_stages())
|
||||
pub fn compile(&self) -> Result<SymbolTable<'_>> {
|
||||
self.compiler_stages()
|
||||
}
|
||||
}
|
||||
|
224
compiler/compiler/src/test.rs
Normal file
224
compiler/compiler/src/test.rs
Normal file
@ -0,0 +1,224 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fmt, fs,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::Compiler;
|
||||
|
||||
use leo_errors::{
|
||||
emitter::{Buffer, Emitter, Handler},
|
||||
LeoError, LeoWarning,
|
||||
};
|
||||
use leo_passes::SymbolTable;
|
||||
use leo_span::symbol::create_session_if_not_set_then;
|
||||
use leo_test_framework::{
|
||||
runner::{Namespace, ParseType, Runner},
|
||||
Test,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Value;
|
||||
|
||||
fn new_compiler(handler: &Handler, main_file_path: PathBuf) -> Compiler<'_> {
|
||||
let output_dir = PathBuf::from("/tmp/output/");
|
||||
fs::create_dir_all(output_dir.clone()).unwrap();
|
||||
|
||||
Compiler::new(handler, main_file_path, output_dir)
|
||||
}
|
||||
|
||||
fn parse_program<'a>(
|
||||
handler: &'a Handler,
|
||||
program_string: &str,
|
||||
cwd: Option<PathBuf>,
|
||||
) -> Result<Compiler<'a>, LeoError> {
|
||||
let mut compiler = new_compiler(handler, cwd.unwrap_or_else(|| "compiler-test".into()));
|
||||
compiler.parse_program_from_string(program_string)?;
|
||||
|
||||
Ok(compiler)
|
||||
}
|
||||
|
||||
fn hash_content(content: &str) -> String {
|
||||
use sha2::{Digest, Sha256};
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(content);
|
||||
let hash = hasher.finalize();
|
||||
|
||||
format!("{:x}", hash)
|
||||
}
|
||||
|
||||
fn hash_file(path: &str) -> String {
|
||||
let file = fs::read_to_string(&Path::new(path)).unwrap();
|
||||
hash_content(&file)
|
||||
}
|
||||
|
||||
struct CompileNamespace;
|
||||
|
||||
impl Namespace for CompileNamespace {
|
||||
fn parse_type(&self) -> ParseType {
|
||||
ParseType::Whole
|
||||
}
|
||||
|
||||
fn run_test(&self, test: Test) -> Result<Value, String> {
|
||||
let buf = BufferEmitter(Rc::default(), Rc::default());
|
||||
let handler = Handler::new(Box::new(buf.clone()));
|
||||
|
||||
create_session_if_not_set_then(|_| run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Serialize)]
|
||||
struct OutputItem {
|
||||
pub initial_input_ast: String,
|
||||
pub symbol_table: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Serialize)]
|
||||
struct CompileOutput {
|
||||
pub output: Vec<OutputItem>,
|
||||
pub initial_ast: String,
|
||||
}
|
||||
|
||||
/// Get the path of the `input_file` given in `input` into `list`.
|
||||
fn get_input_file_paths(list: &mut Vec<PathBuf>, test: &Test, input: &Value) {
|
||||
let input_file: PathBuf = test.path.parent().expect("no test parent dir").into();
|
||||
if input.as_str().is_some() {
|
||||
let mut input_file = input_file;
|
||||
input_file.push(input.as_str().expect("input_file was not a string or array"));
|
||||
list.push(input_file.clone());
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect and return all inputs, if possible.
|
||||
fn collect_all_inputs(test: &Test) -> Result<Vec<PathBuf>, String> {
|
||||
let mut list = vec![];
|
||||
|
||||
if let Some(input) = test.config.get("input_file") {
|
||||
get_input_file_paths(&mut list, test, input);
|
||||
}
|
||||
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
fn compile_and_process<'a>(
|
||||
parsed: &'a mut Compiler<'a>,
|
||||
input_file_path: PathBuf,
|
||||
) -> Result<SymbolTable<'a>, LeoError> {
|
||||
parsed.parse_input(input_file_path)?;
|
||||
parsed.compiler_stages()
|
||||
}
|
||||
|
||||
// Errors used in this module.
|
||||
enum LeoOrString {
|
||||
Leo(LeoError),
|
||||
String(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for LeoOrString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Leo(x) => x.fmt(f),
|
||||
Self::String(x) => x.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A buffer used to emit errors into.
|
||||
#[derive(Clone)]
|
||||
struct BufferEmitter(Rc<RefCell<Buffer<LeoOrString>>>, Rc<RefCell<Buffer<LeoWarning>>>);
|
||||
|
||||
impl Emitter for BufferEmitter {
|
||||
fn emit_err(&mut self, err: LeoError) {
|
||||
self.0.borrow_mut().push(LeoOrString::Leo(err));
|
||||
}
|
||||
|
||||
fn last_emited_err(&self) -> Option<LeoError> {
|
||||
let temp = &*self.0.borrow();
|
||||
temp.last_entry().map(|entry| match entry {
|
||||
LeoOrString::Leo(err) => err.clone(),
|
||||
_ => unimplemented!(),
|
||||
})
|
||||
}
|
||||
|
||||
fn emit_warning(&mut self, warning: leo_errors::LeoWarning) {
|
||||
self.1.borrow_mut().push(warning);
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_if_err<T>(buf: &BufferEmitter, res: Result<T, String>) -> Result<T, ()> {
|
||||
res.map_err(|err| buf.0.borrow_mut().push(LeoOrString::String(err)))
|
||||
}
|
||||
|
||||
fn run_test(test: Test, handler: &Handler, err_buf: &BufferEmitter) -> Result<Value, ()> {
|
||||
// Check for CWD option:
|
||||
// ``` cwd: import ```
|
||||
// When set, uses different working directory for current file.
|
||||
// If not, uses file path as current working directory.
|
||||
let cwd = test.config.get("cwd").map(|val| {
|
||||
let mut cwd = test.path.clone();
|
||||
cwd.pop();
|
||||
cwd.join(&val.as_str().unwrap())
|
||||
});
|
||||
|
||||
let parsed = handler.extend_if_error(parse_program(handler, &test.content, cwd))?;
|
||||
|
||||
// (name, content)
|
||||
let inputs = buffer_if_err(err_buf, collect_all_inputs(&test))?;
|
||||
|
||||
let mut output_items = Vec::with_capacity(inputs.len());
|
||||
|
||||
for input in inputs {
|
||||
let mut parsed = parsed.clone();
|
||||
let symbol_table = handler.extend_if_error(compile_and_process(&mut parsed, input))?;
|
||||
let initial_input_ast = hash_file("/tmp/output/inital_input_ast.json");
|
||||
|
||||
output_items.push(OutputItem {
|
||||
initial_input_ast,
|
||||
symbol_table: hash_content(&symbol_table.to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
let initial_ast = hash_file("/tmp/output/initial_ast.json");
|
||||
|
||||
if fs::read_dir("/tmp/output").is_ok() {
|
||||
fs::remove_dir_all(Path::new("/tmp/output")).expect("Error failed to clean up output dir.");
|
||||
}
|
||||
|
||||
let final_output = CompileOutput {
|
||||
output: output_items,
|
||||
initial_ast,
|
||||
};
|
||||
Ok(serde_yaml::to_value(&final_output).expect("serialization failed"))
|
||||
}
|
||||
|
||||
struct TestRunner;
|
||||
|
||||
impl Runner for TestRunner {
|
||||
fn resolve_namespace(&self, name: &str) -> Option<Box<dyn Namespace>> {
|
||||
Some(match name {
|
||||
"Compile" => Box::new(CompileNamespace),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn compiler_tests() {
|
||||
leo_test_framework::run_tests(&TestRunner, "compiler");
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
[package]
|
||||
name = "leo-input"
|
||||
version = "1.5.3"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "Input parser of the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
repository = "https://github.com/AleoHQ/leo"
|
||||
keywords = [
|
||||
"aleo",
|
||||
"cryptography",
|
||||
"leo",
|
||||
"programming-language",
|
||||
"zero-knowledge"
|
||||
]
|
||||
categories = [ "cryptography::cryptocurrencies", "web-programming" ]
|
||||
include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
|
||||
license = "GPL-3.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
|
||||
[dependencies.from-pest]
|
||||
version = "0.3.1"
|
||||
|
||||
[dependencies.pest]
|
||||
version = "2.0"
|
||||
|
||||
[dependencies.pest-ast]
|
||||
version = "0.3.3"
|
||||
|
||||
[dependencies.pest_derive]
|
||||
version = "2.0"
|
||||
|
||||
[dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.tracing]
|
||||
version = "0.1"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user