merge testnet3, regen tests

This commit is contained in:
collin 2022-07-18 12:32:15 -07:00
commit 5316d900f4
977 changed files with 6315 additions and 12139 deletions

View File

@ -46,7 +46,7 @@ commands:
jobs: jobs:
check-style: check-style:
docker: docker:
- image: cimg/rust:1.59.0 - image: cimg/rust:1.62
resource_class: xlarge resource_class: xlarge
steps: steps:
- checkout - checkout
@ -61,7 +61,7 @@ jobs:
clippy: clippy:
docker: docker:
- image: cimg/rust:1.59.0 - image: cimg/rust:1.62
resource_class: xlarge resource_class: xlarge
steps: steps:
- checkout - checkout
@ -70,13 +70,16 @@ jobs:
- run: - run:
name: Clippy name: Clippy
no_output_timeout: 35m no_output_timeout: 35m
command: cargo clippy --all-features --examples --all --benches command: |
rustup toolchain install nightly-x86_64-unknown-linux-gnu
cargo +nightly clippy --workspace --all-targets -- -D warnings
cargo +nightly clippy --workspace --all-targets --all-features -- -D warnings
- clear_environment: - clear_environment:
cache_key: leo-clippy-cache cache_key: leo-clippy-cache
# code-cov: # code-cov:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# environment: # environment:
# RUSTC_BOOTSTRAP: 1 # RUSTC_BOOTSTRAP: 1
@ -118,7 +121,7 @@ jobs:
leo-executable: leo-executable:
docker: docker:
- image: cimg/rust:1.59.0 - image: cimg/rust:1.62
resource_class: xlarge resource_class: xlarge
steps: steps:
- checkout - checkout
@ -136,7 +139,7 @@ jobs:
# #
# leo-new: # leo-new:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -149,7 +152,7 @@ jobs:
# #
# leo-init: # leo-init:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -162,7 +165,7 @@ jobs:
# #
# leo-clean: # leo-clean:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -175,7 +178,7 @@ jobs:
# #
# leo-setup: # leo-setup:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -188,7 +191,7 @@ jobs:
# leo-add-remove: # leo-add-remove:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -202,7 +205,7 @@ jobs:
# todo (collin): uncomment after compiler refactor # todo (collin): uncomment after compiler refactor
# leo-check-constraints: # leo-check-constraints:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -215,7 +218,7 @@ jobs:
# #
# leo-login-logout: # leo-login-logout:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -228,7 +231,7 @@ jobs:
# #
# leo-clone: # leo-clone:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:
@ -241,7 +244,7 @@ jobs:
# #
# leo-publish: # leo-publish:
# docker: # docker:
# - image: cimg/rust:1.59.0 # - image: cimg/rust:1.62
# resource_class: xlarge # resource_class: xlarge
# steps: # steps:
# - attach_workspace: # - attach_workspace:

1535
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -28,8 +28,9 @@ path = "leo/main.rs"
[workspace] [workspace]
members = [ members = [
"compiler/compiler", "compiler/compiler",
"compiler/parser",
"docs/grammar", "docs/grammar",
"leo/errors", "errors",
"leo/package", "leo/package",
"tests/test-framework", "tests/test-framework",
] ]
@ -39,26 +40,36 @@ path = "./compiler/compiler"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-errors] [dependencies.leo-errors]
path = "./leo/errors" path = "./errors"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-package] [dependencies.leo-package]
path = "./leo/package" path = "./leo/package"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-span] [dependencies.leo-parser]
path = "./leo/span" path = "./compiler/parser"
version = "1.5.3" version = "1.5.3"
[dependencies.snarkvm-utilities] [dependencies.leo-span]
path = "./compiler/span"
version = "1.5.3"
[dependencies.aleo]
git = "https://github.com/AleoHQ/aleo.git"
rev = "220e56"
[dependencies.snarkvm]
#path = "../snarkVM"
git = "https://github.com/AleoHQ/snarkVM.git" git = "https://github.com/AleoHQ/snarkVM.git"
rev = "51633e2" rev = "5657881"
features = ["circuit", "console"]
[dependencies.backtrace] [dependencies.backtrace]
version = "0.3.66" version = "0.3.66"
[dependencies.clap] [dependencies.clap]
version = "3.2.8" version = "3.2"
features = ["derive", "env"] features = ["derive", "env"]
[dependencies.color-backtrace] [dependencies.color-backtrace]

View File

@ -19,15 +19,15 @@ edition = "2021"
rust-version = "1.56" rust-version = "1.56"
[dependencies.leo-errors] [dependencies.leo-errors]
path = "../../leo/errors" path = "../../errors"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-span] [dependencies.leo-span]
path = "../../leo/span" path = "../span"
version = "1.5.3" version = "1.5.3"
[dependencies.indexmap] [dependencies.indexmap]
version = "1.8.0" version = "1.9"
features = [ "serde-1" ] features = [ "serde-1" ]
[dependencies.serde] [dependencies.serde]

View File

@ -14,11 +14,14 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
mod member_access; mod associated_constant_access;
pub use member_access::*; pub use associated_constant_access::*;
mod associated_function_access; mod associated_function_access;
pub use associated_function_access::*; pub use associated_function_access::*;
mod associated_constant_access; mod member_access;
pub use associated_constant_access::*; pub use member_access::*;
mod tuple_access;
pub use tuple_access::*;

View File

@ -14,30 +14,27 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{commands::Command, context::Context}; use crate::{Expression, Node, PositiveNumber};
use leo_errors::Result; use leo_span::Span;
use structopt::StructOpt; use serde::{Deserialize, Serialize};
use tracing::span::Span; use std::fmt;
/// Deploy Leo program to the network /// An tuple access expression, e.g., `tuple.index`.
#[derive(StructOpt, Debug)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)] pub struct TupleAccess {
pub struct Deploy {} /// 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 Command for Deploy { impl fmt::Display for TupleAccess {
type Input = (); fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
type Output = (); write!(f, "{}.{}", self.tuple, self.index)
fn log_span(&self) -> Span {
tracing::span!(tracing::Level::INFO, "Deploy")
}
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}
fn apply(self, _: Context, _: Self::Input) -> Result<Self::Output> {
unimplemented!("Deploy command has not been implemented yet");
} }
} }
crate::simple_node_impl!(TupleAccess);

View File

@ -16,6 +16,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::str::FromStr;
/// A number string guaranteed to be positive. /// A number string guaranteed to be positive.
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
@ -30,6 +31,10 @@ impl PositiveNumber {
pub fn is_zero(&self) -> bool { pub fn is_zero(&self) -> bool {
self.value.eq("0") self.value.eq("0")
} }
pub fn to_usize(&self) -> usize {
usize::from_str(&self.value).expect("failed to parse positive number")
}
} }
impl fmt::Display for PositiveNumber { impl fmt::Display for PositiveNumber {

View File

@ -27,30 +27,32 @@ pub enum AccessExpression {
// Array(ArrayAccess), // Array(ArrayAccess),
// /// An expression accessing a range of an array. // /// An expression accessing a range of an array.
// ArrayRange(ArrayRangeAccess), // 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 an associated variable of a circuit e.g `u8::MAX`. /// Access to an associated variable of a circuit e.g `u8::MAX`.
AssociatedConstant(AssociatedConstant), AssociatedConstant(AssociatedConstant),
/// Access to an associated function of a circuit e.g `Pedersen64::hash()`. /// Access to an associated function of a circuit e.g `Pedersen64::hash()`.
AssociatedFunction(AssociatedFunction), AssociatedFunction(AssociatedFunction),
/// 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),
} }
impl Node for AccessExpression { impl Node for AccessExpression {
fn span(&self) -> Span { fn span(&self) -> Span {
match self { match self {
AccessExpression::Member(n) => n.span(),
AccessExpression::AssociatedConstant(n) => n.span(), AccessExpression::AssociatedConstant(n) => n.span(),
AccessExpression::AssociatedFunction(n) => n.span(), AccessExpression::AssociatedFunction(n) => n.span(),
AccessExpression::Member(n) => n.span(),
AccessExpression::Tuple(n) => n.span(),
} }
} }
fn set_span(&mut self, span: Span) { fn set_span(&mut self, span: Span) {
match self { match self {
AccessExpression::Member(n) => n.set_span(span),
AccessExpression::AssociatedConstant(n) => n.set_span(span), AccessExpression::AssociatedConstant(n) => n.set_span(span),
AccessExpression::AssociatedFunction(n) => n.set_span(span), AccessExpression::AssociatedFunction(n) => n.set_span(span),
AccessExpression::Member(n) => n.set_span(span),
AccessExpression::Tuple(n) => n.set_span(span),
} }
} }
} }
@ -60,12 +62,10 @@ impl fmt::Display for AccessExpression {
use AccessExpression::*; use AccessExpression::*;
match self { match self {
// Array(access) => access.fmt(f),
// ArrayRange(access) => access.fmt(f),
Member(access) => access.fmt(f),
// Tuple(access) => access.fmt(f),
AssociatedConstant(access) => access.fmt(f), AssociatedConstant(access) => access.fmt(f),
AssociatedFunction(access) => access.fmt(f), AssociatedFunction(access) => access.fmt(f),
Member(access) => access.fmt(f),
Tuple(access) => access.fmt(f),
} }
} }
} }

View File

@ -38,7 +38,7 @@ impl fmt::Display for CircuitVariableInitializer {
/// A circuit initialization expression, e.g., `Foo { bar: 42, baz }`. /// A circuit initialization expression, e.g., `Foo { bar: 42, baz }`.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CircuitInitExpression { pub struct CircuitExpression {
/// The name of the structure type to initialize. /// The name of the structure type to initialize.
pub name: Identifier, pub name: Identifier,
/// Initializer expressions for each of the fields in the circuit. /// Initializer expressions for each of the fields in the circuit.
@ -50,15 +50,18 @@ pub struct CircuitInitExpression {
pub span: Span, pub span: Span,
} }
impl fmt::Display for CircuitInitExpression { impl fmt::Display for CircuitExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {{ ", self.name)?; write!(
for member in self.members.iter() { f,
write!(f, "{}", member)?; "{{{}}}",
write!(f, ", ")?; self.members
} .iter()
write!(f, "}}") .map(|x| x.to_string())
.collect::<Vec<_>>()
.join(", ")
)
} }
} }
crate::simple_node_impl!(CircuitInitExpression); crate::simple_node_impl!(CircuitExpression);

View File

@ -46,10 +46,10 @@ impl fmt::Display for Literal {
match &self { match &self {
Self::Address(address, _) => write!(f, "{}", address), Self::Address(address, _) => write!(f, "{}", address),
Self::Boolean(boolean, _) => write!(f, "{}", boolean), Self::Boolean(boolean, _) => write!(f, "{}", boolean),
Self::Field(field, _) => write!(f, "{}", field), Self::Field(field, _) => write!(f, "{}field", field),
Self::Group(group) => write!(f, "{}", group), Self::Group(group) => write!(f, "{}group", group),
Self::Integer(type_, value, _) => write!(f, "{}{}", value, type_), Self::Integer(type_, value, _) => write!(f, "{}{}", value, type_),
Self::Scalar(scalar, _) => write!(f, "{}", scalar), Self::Scalar(scalar, _) => write!(f, "{}scalar", scalar),
Self::String(string, _) => write!(f, "{}", string), Self::String(string, _) => write!(f, "{}", string),
} }
} }

View File

@ -38,6 +38,9 @@ pub use err::*;
mod ternary; mod ternary;
pub use ternary::*; pub use ternary::*;
mod tuple_init;
pub use tuple_init::*;
mod unary; mod unary;
pub use unary::*; pub use unary::*;
@ -49,21 +52,23 @@ pub use literal::*;
pub enum Expression { pub enum Expression {
/// A circuit access expression, e.g., `Foo.bar`. /// A circuit access expression, e.g., `Foo.bar`.
Access(AccessExpression), Access(AccessExpression),
/// An identifier expression.
Identifier(Identifier),
/// A literal expression.
Literal(Literal),
/// A binary expression, e.g., `42 + 24`. /// A binary expression, e.g., `42 + 24`.
Binary(BinaryExpression), Binary(BinaryExpression),
/// A call expression, e.g., `my_fun(args)`. /// A call expression, e.g., `my_fun(args)`.
Call(CallExpression), Call(CallExpression),
/// An expression constructing a circuit like `Foo { bar: 42, baz }`. /// An expression constructing a circuit like `Foo { bar: 42, baz }`.
CircuitInit(CircuitInitExpression), Circuit(CircuitExpression),
/// An expression of type "error". /// An expression of type "error".
/// Will result in a compile error eventually. /// Will result in a compile error eventually.
Err(ErrExpression), Err(ErrExpression),
/// An identifier.
Identifier(Identifier),
/// A literal expression.
Literal(Literal),
/// A ternary conditional expression `cond ? if_expr : else_expr`. /// A ternary conditional expression `cond ? if_expr : else_expr`.
Ternary(TernaryExpression), Ternary(TernaryExpression),
/// A tuple expression e.g., `(foo, 42, true)`.
Tuple(TupleExpression),
/// An unary expression. /// An unary expression.
Unary(UnaryExpression), Unary(UnaryExpression),
} }
@ -73,13 +78,14 @@ impl Node for Expression {
use Expression::*; use Expression::*;
match self { match self {
Access(n) => n.span(), Access(n) => n.span(),
Identifier(n) => n.span(),
Literal(n) => n.span(),
Binary(n) => n.span(), Binary(n) => n.span(),
Call(n) => n.span(), Call(n) => n.span(),
CircuitInit(n) => n.span(), Circuit(n) => n.span(),
Err(n) => n.span(), Err(n) => n.span(),
Identifier(n) => n.span(),
Literal(n) => n.span(),
Ternary(n) => n.span(), Ternary(n) => n.span(),
Tuple(n) => n.span(),
Unary(n) => n.span(), Unary(n) => n.span(),
} }
} }
@ -88,13 +94,14 @@ impl Node for Expression {
use Expression::*; use Expression::*;
match self { match self {
Access(n) => n.set_span(span), Access(n) => n.set_span(span),
Identifier(n) => n.set_span(span),
Literal(n) => n.set_span(span),
Binary(n) => n.set_span(span), Binary(n) => n.set_span(span),
Call(n) => n.set_span(span), Call(n) => n.set_span(span),
CircuitInit(n) => n.set_span(span), Circuit(n) => n.set_span(span),
Identifier(n) => n.set_span(span),
Literal(n) => n.set_span(span),
Err(n) => n.set_span(span), Err(n) => n.set_span(span),
Ternary(n) => n.set_span(span), Ternary(n) => n.set_span(span),
Tuple(n) => n.set_span(span),
Unary(n) => n.set_span(span), Unary(n) => n.set_span(span),
} }
} }
@ -105,13 +112,14 @@ impl fmt::Display for Expression {
use Expression::*; use Expression::*;
match &self { match &self {
Access(n) => n.fmt(f), Access(n) => n.fmt(f),
Identifier(n) => n.fmt(f),
Literal(n) => n.fmt(f),
Binary(n) => n.fmt(f), Binary(n) => n.fmt(f),
Call(n) => n.fmt(f), Call(n) => n.fmt(f),
CircuitInit(n) => n.fmt(f), Circuit(n) => n.fmt(f),
Err(n) => n.fmt(f), Err(n) => n.fmt(f),
Identifier(n) => n.fmt(f),
Literal(n) => n.fmt(f),
Ternary(n) => n.fmt(f), Ternary(n) => n.fmt(f),
Tuple(n) => n.fmt(f),
Unary(n) => n.fmt(f), Unary(n) => n.fmt(f),
} }
} }

View File

@ -14,30 +14,30 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{commands::Command, context::Context}; use super::*;
use leo_errors::Result;
use structopt::StructOpt; /// A tuple construction expression, e.g., `(foo, false, 42)`.
use tracing::span::Span; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TupleExpression {
/// 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,
}
/// Lint Leo code command impl fmt::Display for TupleExpression {
#[derive(StructOpt, Debug)] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)] write!(
pub struct Lint {} f,
"({})",
impl Command for Lint { self.elements
type Input = (); .iter()
type Output = (); .map(|x| x.to_string())
.collect::<Vec<_>>()
fn log_span(&self) -> Span { .join(",")
tracing::span!(tracing::Level::INFO, "Linting") )
}
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}
fn apply(self, _: Context, _: Self::Input) -> Result<Self::Output> {
unimplemented!("Lint command has not been implemented yet");
} }
} }
crate::simple_node_impl!(TupleExpression);

View File

@ -19,11 +19,10 @@ use crate::{normalize_json_value, remove_key_from_json};
use super::*; use super::*;
use leo_errors::{AstError, Result}; use leo_errors::{AstError, Result};
/// Input data which includes [`ProgramInput`] and [`ProgramState`]. /// Input data which includes [`ProgramInput`].
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Input { pub struct Input {
pub program_input: ProgramInput, pub program_input: ProgramInput,
pub program_state: ProgramState,
} }
impl Input { impl Input {
@ -34,13 +33,27 @@ impl Input {
} }
/// A raw unprocessed input or state file data. Used for future conversion /// A raw unprocessed input or state file data. Used for future conversion
/// into [`ProgramInput`] or [`ProgramState`]. /// into [`ProgramInput`].
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct InputAst { pub struct InputAst {
pub sections: Vec<Section>, pub sections: Vec<Section>,
} }
impl InputAst { impl InputAst {
/// Returns all values of the input AST for execution with `leo run`.
pub fn program_inputs(&self, program_name: &str) -> Vec<String> {
self.sections
.iter()
.filter(|section| section.name() == program_name)
.flat_map(|section| {
section
.definitions
.iter()
.map(|definition| definition.value.to_string())
})
.collect::<Vec<_>>()
}
/// Serializes the `Input` into a JSON Value. /// Serializes the `Input` into a JSON Value.
pub fn to_json_value(&self) -> Result<serde_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))?) Ok(serde_json::to_value(&self).map_err(|e| AstError::failed_to_convert_ast_to_json_value(&e))?)

View File

@ -26,9 +26,6 @@ pub use input_value::*;
pub mod program_input; pub mod program_input;
pub use program_input::*; pub use program_input::*;
pub mod program_state;
pub use program_state::*;
pub mod section; pub mod section;
pub use section::*; pub use section::*;

View File

@ -20,24 +20,17 @@ use super::*;
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ProgramInput { pub struct ProgramInput {
pub main: Definitions, pub main: Definitions,
pub registers: Definitions,
} }
impl TryFrom<InputAst> for ProgramInput { impl TryFrom<InputAst> for ProgramInput {
type Error = LeoError; type Error = LeoError;
fn try_from(input: InputAst) -> Result<Self> { fn try_from(input: InputAst) -> Result<Self> {
let mut main = IndexMap::new(); let mut main = IndexMap::new();
let mut registers = IndexMap::new();
for section in input.sections { for section in input.sections {
let target = match section.name { let target = match section.name {
sym::main => &mut main, sym::main => &mut main,
sym::registers => &mut registers, _ => return Err(InputError::unexpected_section(&["main"], section.name, section.span).into()),
_ => {
return Err(
InputError::unexpected_section(&["main", "registers"], section.name, section.span).into(),
)
}
}; };
for definition in section.definitions { for definition in section.definitions {
@ -48,6 +41,6 @@ impl TryFrom<InputAst> for ProgramInput {
} }
} }
Ok(ProgramInput { main, registers }) Ok(ProgramInput { main })
} }
} }

View File

@ -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::*;
/// Processed Program state.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ProgramState {
pub state: Definitions,
}
impl TryFrom<InputAst> for ProgramState {
type Error = LeoError;
fn try_from(input: InputAst) -> Result<Self> {
let mut state = IndexMap::new();
for section in input.sections {
if matches!(section.name, sym::state | sym::record | sym::state_leaf) {
for definition in section.definitions {
state.insert(
definition.name.name,
InputValue::try_from((definition.type_, definition.value))?,
);
}
} else {
return Err(InputError::unexpected_section(
&["state", "record", "state_leaf"],
section.name,
section.span,
)
.into());
}
}
Ok(ProgramState { state })
}
}

View File

@ -24,3 +24,9 @@ pub struct Section {
pub definitions: Vec<Definition>, pub definitions: Vec<Definition>,
pub span: Span, pub span: Span,
} }
impl Section {
pub fn name(&self) -> String {
self.name.to_string()
}
}

View File

@ -74,6 +74,18 @@ impl Ast {
Self { ast: program } Self { ast: program }
} }
/// Set the program name to the given string.
pub fn set_program_name(mut self, name: String) -> Self {
self.ast.name = name;
self
}
/// Set the network name to the given string.
pub fn set_network(mut self, network: String) -> Self {
self.ast.network = network;
self
}
/// Returns a reference to the inner program AST representation. /// Returns a reference to the inner program AST representation.
pub fn as_repr(&self) -> &Program { pub fn as_repr(&self) -> &Program {
&self.ast &self.ast

View File

@ -27,31 +27,47 @@ pub trait ExpressionReconstructor {
fn reconstruct_expression(&mut self, input: Expression) -> (Expression, Self::AdditionalOutput) { fn reconstruct_expression(&mut self, input: Expression) -> (Expression, Self::AdditionalOutput) {
match input { match input {
Expression::Access(access) => self.reconstruct_access(access), Expression::Access(access) => self.reconstruct_access(access),
Expression::Identifier(identifier) => self.reconstruct_identifier(identifier),
Expression::Literal(value) => self.reconstruct_literal(value),
Expression::Binary(binary) => self.reconstruct_binary(binary), Expression::Binary(binary) => self.reconstruct_binary(binary),
Expression::Call(call) => self.reconstruct_call(call), Expression::Call(call) => self.reconstruct_call(call),
Expression::CircuitInit(circuit) => self.reconstruct_circuit_init(circuit), Expression::Circuit(circuit) => self.reconstruct_circuit_init(circuit),
Expression::Unary(unary) => self.reconstruct_unary(unary),
Expression::Ternary(ternary) => self.reconstruct_ternary(ternary),
Expression::Err(err) => self.reconstruct_err(err), Expression::Err(err) => self.reconstruct_err(err),
Expression::Identifier(identifier) => self.reconstruct_identifier(identifier),
Expression::Literal(value) => self.reconstruct_literal(value),
Expression::Ternary(ternary) => self.reconstruct_ternary(ternary),
Expression::Tuple(tuple) => self.reconstruct_tuple(tuple),
Expression::Unary(unary) => self.reconstruct_unary(unary),
} }
} }
fn reconstruct_identifier(&mut self, input: Identifier) -> (Expression, Self::AdditionalOutput) {
(Expression::Identifier(input), Default::default())
}
fn reconstruct_literal(&mut self, input: Literal) -> (Expression, Self::AdditionalOutput) {
(Expression::Literal(input), Default::default())
}
fn reconstruct_access(&mut self, input: AccessExpression) -> (Expression, Self::AdditionalOutput) { fn reconstruct_access(&mut self, input: AccessExpression) -> (Expression, Self::AdditionalOutput) {
(Expression::Access(input), Default::default()) (
} Expression::Access(match input {
AccessExpression::AssociatedFunction(function) => {
fn reconstruct_circuit_init(&mut self, input: CircuitInitExpression) -> (Expression, Self::AdditionalOutput) { AccessExpression::AssociatedFunction(AssociatedFunction {
(Expression::CircuitInit(input), Default::default()) ty: function.ty,
name: function.name,
args: function
.args
.into_iter()
.map(|arg| self.reconstruct_expression(arg).0)
.collect(),
span: function.span,
})
}
AccessExpression::Member(member) => AccessExpression::Member(MemberAccess {
inner: Box::new(self.reconstruct_expression(*member.inner).0),
name: member.name,
span: member.span,
}),
AccessExpression::Tuple(tuple) => AccessExpression::Tuple(TupleAccess {
tuple: Box::new(self.reconstruct_expression(*tuple.tuple).0),
index: tuple.index,
span: tuple.span,
}),
expr => expr,
}),
Default::default(),
)
} }
fn reconstruct_binary(&mut self, input: BinaryExpression) -> (Expression, Self::AdditionalOutput) { fn reconstruct_binary(&mut self, input: BinaryExpression) -> (Expression, Self::AdditionalOutput) {
@ -66,29 +82,6 @@ pub trait ExpressionReconstructor {
) )
} }
fn reconstruct_unary(&mut self, input: UnaryExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Unary(UnaryExpression {
receiver: Box::new(self.reconstruct_expression(*input.receiver).0),
op: input.op,
span: input.span,
}),
Default::default(),
)
}
fn reconstruct_ternary(&mut self, input: TernaryExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Ternary(TernaryExpression {
condition: Box::new(self.reconstruct_expression(*input.condition).0),
if_true: Box::new(self.reconstruct_expression(*input.if_true).0),
if_false: Box::new(self.reconstruct_expression(*input.if_false).0),
span: input.span,
}),
Default::default(),
)
}
fn reconstruct_call(&mut self, input: CallExpression) -> (Expression, Self::AdditionalOutput) { fn reconstruct_call(&mut self, input: CallExpression) -> (Expression, Self::AdditionalOutput) {
( (
Expression::Call(CallExpression { Expression::Call(CallExpression {
@ -104,9 +97,58 @@ pub trait ExpressionReconstructor {
) )
} }
fn reconstruct_circuit_init(&mut self, input: CircuitExpression) -> (Expression, Self::AdditionalOutput) {
(Expression::Circuit(input), Default::default())
}
fn reconstruct_err(&mut self, input: ErrExpression) -> (Expression, Self::AdditionalOutput) { fn reconstruct_err(&mut self, input: ErrExpression) -> (Expression, Self::AdditionalOutput) {
(Expression::Err(input), Default::default()) (Expression::Err(input), Default::default())
} }
fn reconstruct_identifier(&mut self, input: Identifier) -> (Expression, Self::AdditionalOutput) {
(Expression::Identifier(input), Default::default())
}
fn reconstruct_literal(&mut self, input: Literal) -> (Expression, Self::AdditionalOutput) {
(Expression::Literal(input), Default::default())
}
fn reconstruct_ternary(&mut self, input: TernaryExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Ternary(TernaryExpression {
condition: Box::new(self.reconstruct_expression(*input.condition).0),
if_true: Box::new(self.reconstruct_expression(*input.if_true).0),
if_false: Box::new(self.reconstruct_expression(*input.if_false).0),
span: input.span,
}),
Default::default(),
)
}
fn reconstruct_tuple(&mut self, input: TupleExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Tuple(TupleExpression {
elements: input
.elements
.into_iter()
.map(|element| self.reconstruct_expression(element).0)
.collect(),
span: input.span,
}),
Default::default(),
)
}
fn reconstruct_unary(&mut self, input: UnaryExpression) -> (Expression, Self::AdditionalOutput) {
(
Expression::Unary(UnaryExpression {
receiver: Box::new(self.reconstruct_expression(*input.receiver).0),
op: input.op,
span: input.span,
}),
Default::default(),
)
}
} }
/// A Reconstructor trait for statements in the AST. /// A Reconstructor trait for statements in the AST.
@ -214,7 +256,13 @@ pub trait ProgramReconstructor: StatementReconstructor {
fn reconstruct_program(&mut self, input: Program) -> Program { fn reconstruct_program(&mut self, input: Program) -> Program {
Program { Program {
name: input.name, name: input.name,
network: input.network,
expected_input: input.expected_input, expected_input: input.expected_input,
imports: input
.imports
.into_iter()
.map(|(id, import)| (id, self.reconstruct_import(import)))
.collect(),
functions: input functions: input
.functions .functions
.into_iter() .into_iter()
@ -242,4 +290,8 @@ pub trait ProgramReconstructor: StatementReconstructor {
fn reconstruct_circuit(&mut self, input: Circuit) -> Circuit { fn reconstruct_circuit(&mut self, input: Circuit) -> Circuit {
input input
} }
fn reconstruct_import(&mut self, input: Program) -> Program {
input
}
} }

View File

@ -27,30 +27,63 @@ pub trait ExpressionVisitor<'a> {
fn visit_expression(&mut self, input: &'a Expression, additional: &Self::AdditionalInput) -> Self::Output { fn visit_expression(&mut self, input: &'a Expression, additional: &Self::AdditionalInput) -> Self::Output {
match input { match input {
Expression::Access(expr) => self.visit_access(expr, additional), Expression::Access(access) => self.visit_access(access, additional),
Expression::CircuitInit(expr) => self.visit_circuit_init(expr, additional), Expression::Binary(binary) => self.visit_binary(binary, additional),
Expression::Identifier(expr) => self.visit_identifier(expr, additional), Expression::Call(call) => self.visit_call(call, additional),
Expression::Literal(expr) => self.visit_literal(expr, additional), Expression::Circuit(circuit) => self.visit_circuit_init(circuit, additional),
Expression::Binary(expr) => self.visit_binary(expr, additional), Expression::Err(err) => self.visit_err(err, additional),
Expression::Unary(expr) => self.visit_unary(expr, additional), Expression::Identifier(identifier) => self.visit_identifier(identifier, additional),
Expression::Ternary(expr) => self.visit_ternary(expr, additional), Expression::Literal(literal) => self.visit_literal(literal, additional),
Expression::Call(expr) => self.visit_call(expr, additional), Expression::Ternary(ternary) => self.visit_ternary(ternary, additional),
Expression::Err(expr) => self.visit_err(expr, additional), Expression::Tuple(tuple) => self.visit_tuple(tuple, additional),
Expression::Unary(unary) => self.visit_unary(unary, additional),
} }
} }
fn visit_access(&mut self, _input: &'a AccessExpression, _additional: &Self::AdditionalInput) -> Self::Output { fn visit_access(&mut self, input: &'a AccessExpression, additional: &Self::AdditionalInput) -> Self::Output {
match input {
AccessExpression::AssociatedFunction(function) => {
function.args.iter().for_each(|arg| {
self.visit_expression(arg, &Default::default());
});
}
AccessExpression::Member(member) => {
self.visit_expression(&member.inner, additional);
}
AccessExpression::Tuple(tuple) => {
self.visit_expression(&tuple.tuple, additional);
}
_ => {}
}
Default::default()
}
fn visit_binary(&mut self, input: &'a BinaryExpression, additional: &Self::AdditionalInput) -> Self::Output {
self.visit_expression(&input.left, additional);
self.visit_expression(&input.right, additional);
Default::default()
}
fn visit_call(&mut self, input: &'a CallExpression, additional: &Self::AdditionalInput) -> Self::Output {
input.arguments.iter().for_each(|expr| {
self.visit_expression(expr, additional);
});
Default::default() Default::default()
} }
fn visit_circuit_init( fn visit_circuit_init(
&mut self, &mut self,
_input: &'a CircuitInitExpression, _input: &'a CircuitExpression,
_additional: &Self::AdditionalInput, _additional: &Self::AdditionalInput,
) -> Self::Output { ) -> Self::Output {
Default::default() Default::default()
} }
fn visit_err(&mut self, _input: &'a ErrExpression, _additional: &Self::AdditionalInput) -> Self::Output {
Default::default()
}
fn visit_identifier(&mut self, _input: &'a Identifier, _additional: &Self::AdditionalInput) -> Self::Output { fn visit_identifier(&mut self, _input: &'a Identifier, _additional: &Self::AdditionalInput) -> Self::Output {
Default::default() Default::default()
} }
@ -59,17 +92,6 @@ pub trait ExpressionVisitor<'a> {
Default::default() Default::default()
} }
fn visit_binary(&mut self, input: &'a BinaryExpression, additional: &Self::AdditionalInput) -> Self::Output {
self.visit_expression(&input.left, additional);
self.visit_expression(&input.right, additional);
Default::default()
}
fn visit_unary(&mut self, input: &'a UnaryExpression, additional: &Self::AdditionalInput) -> Self::Output {
self.visit_expression(&input.receiver, additional);
Default::default()
}
fn visit_ternary(&mut self, input: &'a TernaryExpression, additional: &Self::AdditionalInput) -> Self::Output { fn visit_ternary(&mut self, input: &'a TernaryExpression, additional: &Self::AdditionalInput) -> Self::Output {
self.visit_expression(&input.condition, additional); self.visit_expression(&input.condition, additional);
self.visit_expression(&input.if_true, additional); self.visit_expression(&input.if_true, additional);
@ -77,14 +99,15 @@ pub trait ExpressionVisitor<'a> {
Default::default() Default::default()
} }
fn visit_call(&mut self, input: &'a CallExpression, additional: &Self::AdditionalInput) -> Self::Output { fn visit_tuple(&mut self, input: &'a TupleExpression, additional: &Self::AdditionalInput) -> Self::Output {
input.arguments.iter().for_each(|expr| { input.elements.iter().for_each(|expr| {
self.visit_expression(expr, additional); self.visit_expression(expr, additional);
}); });
Default::default() Default::default()
} }
fn visit_err(&mut self, _input: &'a ErrExpression, _additional: &Self::AdditionalInput) -> Self::Output { fn visit_unary(&mut self, input: &'a UnaryExpression, additional: &Self::AdditionalInput) -> Self::Output {
self.visit_expression(&input.receiver, additional);
Default::default() Default::default()
} }
} }
@ -150,6 +173,8 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
/// A Visitor trait for the program represented by the AST. /// A Visitor trait for the program represented by the AST.
pub trait ProgramVisitor<'a>: StatementVisitor<'a> { pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
fn visit_program(&mut self, input: &'a Program) { fn visit_program(&mut self, input: &'a Program) {
input.imports.values().for_each(|import| self.visit_import(import));
input input
.functions .functions
.values() .values()
@ -166,4 +191,8 @@ pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
} }
fn visit_circuit(&mut self, _input: &'a Circuit) {} fn visit_circuit(&mut self, _input: &'a Circuit) {}
fn visit_import(&mut self, input: &'a Program) {
self.visit_program(input)
}
} }

View File

@ -27,11 +27,14 @@ use std::fmt;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Program { pub struct Program {
/// The name of the program. /// The name of the program.
/// Empty after parsing.
pub name: String, pub name: String,
/// The network of the program.
pub network: String,
/// Expected main function inputs. /// Expected main function inputs.
/// Empty after parsing. /// Empty after parsing.
pub expected_input: Vec<FunctionInput>, pub expected_input: Vec<FunctionInput>,
/// A map from import names to import definitions.
pub imports: IndexMap<Identifier, Program>,
/// A map from function names to function definitions. /// A map from function names to function definitions.
pub functions: IndexMap<Identifier, Function>, pub functions: IndexMap<Identifier, Function>,
/// A map from circuit names to circuit definitions. /// A map from circuit names to circuit definitions.
@ -40,6 +43,9 @@ pub struct Program {
impl fmt::Display for Program { impl fmt::Display for Program {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (id, _import) in self.imports.iter() {
writeln!(f, "import {}.leo;", id)?;
}
for (_, function) in self.functions.iter() { for (_, function) in self.functions.iter() {
function.fmt(f)?; function.fmt(f)?;
writeln!(f,)?; writeln!(f,)?;
@ -52,25 +58,16 @@ impl fmt::Display for Program {
} }
} }
impl Program { impl Default for Program {
/// Constructs an empty program with `name`. /// Constructs an empty program node.
pub fn new(name: String) -> Self { fn default() -> Self {
Self { Self {
name, name: String::new(),
network: String::new(),
expected_input: vec![], expected_input: vec![],
imports: IndexMap::new(),
functions: IndexMap::new(), functions: IndexMap::new(),
circuits: IndexMap::new(), circuits: IndexMap::new(),
} }
} }
/// Extract the name of the program.
pub fn name(&self) -> &str {
&self.name
}
/// Sets the name of the program.
pub fn set_name(mut self, name: String) -> Self {
self.name = name;
self
}
} }

View File

@ -17,5 +17,8 @@
pub mod integer_type; pub mod integer_type;
pub use integer_type::*; pub use integer_type::*;
pub mod tuple;
pub use tuple::*;
pub mod type_; pub mod type_;
pub use type_::*; pub use type_::*;

View File

@ -0,0 +1,55 @@
// 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 leo_errors::{AstError, Result};
use leo_span::Span;
use serde::{Deserialize, Serialize};
use std::{fmt, ops::Deref};
/// A type list of at least two types.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Tuple(Vec<Type>);
impl Tuple {
/// Returns a new `Type::Tuple` enumeration.
pub fn try_new(elements: Vec<Type>, span: Span) -> Result<Type> {
match elements.len() {
0 => Err(AstError::empty_tuple(span).into()),
1 => Err(AstError::one_element_tuple(span).into()),
_ => Ok(Type::Tuple(Tuple(elements))),
}
}
}
impl Deref for Tuple {
type Target = Vec<Type>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Display for Tuple {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"({})",
self.0.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",")
)
}
}

View File

@ -14,13 +14,13 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Identifier, IntegerType}; use crate::{Identifier, IntegerType, Tuple};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
/// Explicit type used for defining a variable or expression type /// Explicit type used for defining a variable or expression type
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Type { pub enum Type {
// Data types // Data types
/// The `address` type. /// The `address` type.
@ -39,6 +39,8 @@ pub enum Type {
IntegerType(IntegerType), IntegerType(IntegerType),
/// A reference to a built in type. /// A reference to a built in type.
Identifier(Identifier), Identifier(Identifier),
/// A static tuple of at least one type.
Tuple(Tuple),
/// Placeholder for a type that could not be resolved or was not well-formed. /// Placeholder for a type that could not be resolved or was not well-formed.
/// Will eventually lead to a compile error. /// Will eventually lead to a compile error.
@ -61,6 +63,10 @@ impl Type {
| (Type::Scalar, Type::Scalar) | (Type::Scalar, Type::Scalar)
| (Type::String, Type::String) => true, | (Type::String, Type::String) => true,
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right), (Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
(Type::Tuple(left), Type::Tuple(right)) => left
.iter()
.zip(right.iter())
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
(Type::Identifier(left), Type::Identifier(right)) => left.matches(right), (Type::Identifier(left), Type::Identifier(right)) => left.matches(right),
_ => false, _ => false,
} }
@ -78,6 +84,7 @@ impl fmt::Display for Type {
Type::String => write!(f, "string"), Type::String => write!(f, "string"),
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type), Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
Type::Identifier(ref variable) => write!(f, "circuit {}", variable), Type::Identifier(ref variable) => write!(f, "circuit {}", variable),
Type::Tuple(ref tuple) => write!(f, "{}", tuple),
Type::Err => write!(f, "error"), Type::Err => write!(f, "error"),
} }
} }

View File

@ -23,7 +23,7 @@ path = "../ast"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-errors] [dependencies.leo-errors]
path = "../../leo/errors" path = "../../errors"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-passes] [dependencies.leo-passes]
@ -34,23 +34,23 @@ version = "1.5.3"
path = "../parser" path = "../parser"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-span]
path = "../span"
version = "1.5.3"
[dependencies.sha2] [dependencies.sha2]
version = "0.10" version = "0.10"
[dependencies.leo-span]
path = "../../leo/span"
version = "1.5.3"
[dev-dependencies.leo-test-framework] [dev-dependencies.leo-test-framework]
path = "../../tests/test-framework" path = "../../tests/test-framework"
version = "1.4.0" version = "1.4.0"
[dev-dependencies.serde] [dev-dependencies.serde]
version = "1.0.138" version = "1.0.139"
features = ["derive"] features = ["derive"]
[dev-dependencies.serde_yaml] [dev-dependencies.serde_yaml]
version = "0.8.24" version = "0.8.25"
[features] [features]
default = [] default = []

View File

@ -41,6 +41,10 @@ pub struct Compiler<'a> {
main_file_path: PathBuf, main_file_path: PathBuf,
/// The path to where the compiler outputs all generated files. /// The path to where the compiler outputs all generated files.
output_directory: PathBuf, output_directory: PathBuf,
/// The program name,
pub program_name: String,
/// The network name,
pub network: String,
/// The AST for the program. /// The AST for the program.
pub ast: Ast, pub ast: Ast,
/// The input ast for the program if it exists. /// The input ast for the program if it exists.
@ -54,6 +58,8 @@ impl<'a> Compiler<'a> {
/// Returns a new Leo compiler. /// Returns a new Leo compiler.
/// ///
pub fn new( pub fn new(
program_name: String,
network: String,
handler: &'a Handler, handler: &'a Handler,
main_file_path: PathBuf, main_file_path: PathBuf,
output_directory: PathBuf, output_directory: PathBuf,
@ -63,7 +69,9 @@ impl<'a> Compiler<'a> {
handler, handler,
main_file_path, main_file_path,
output_directory, output_directory,
ast: Ast::new(Program::new("Initial".to_string())), program_name,
network,
ast: Ast::new(Program::default()),
input_ast: None, input_ast: None,
output_options: output_options.unwrap_or_default(), output_options: output_options.unwrap_or_default(),
} }
@ -91,7 +99,9 @@ impl<'a> Compiler<'a> {
let prg_sf = with_session_globals(|s| s.source_map.new_source(program_string, name)); let prg_sf = with_session_globals(|s| s.source_map.new_source(program_string, name));
// Use the parser to construct the abstract syntax tree (ast). // Use the parser to construct the abstract syntax tree (ast).
let ast: leo_ast::Ast = leo_parser::parse_ast(self.handler, &prg_sf.src, prg_sf.start_pos)?; let mut ast: leo_ast::Ast = leo_parser::parse_ast(self.handler, &prg_sf.src, prg_sf.start_pos)?;
ast = ast.set_program_name(self.program_name.clone());
ast = ast.set_network(self.network.clone());
if self.output_options.ast_initial { if self.output_options.ast_initial {
// Write the AST snapshot post parsing. // Write the AST snapshot post parsing.
@ -166,6 +176,19 @@ impl<'a> Compiler<'a> {
Ok(st) Ok(st)
} }
///
/// Returns a compiled Leo program and prints the resulting bytecode.
/// TODO: Remove when code generation is ready to be integrated into the compiler.
///
pub fn compile_and_generate_instructions(&mut self) -> Result<(SymbolTable, String)> {
self.parse_program()?;
let symbol_table = self.compiler_stages()?;
let bytecode = CodeGenerator::do_pass((&self.ast, self.handler))?;
Ok((symbol_table, bytecode))
}
/// ///
/// Returns a compiled Leo program. /// Returns a compiled Leo program.
/// ///

View File

@ -41,6 +41,8 @@ fn new_compiler(handler: &Handler, main_file_path: PathBuf) -> Compiler<'_> {
fs::create_dir_all(output_dir.clone()).unwrap(); fs::create_dir_all(output_dir.clone()).unwrap();
Compiler::new( Compiler::new(
String::from("test"),
String::from("testnet3"),
handler, handler,
main_file_path, main_file_path,
output_dir, output_dir,

View File

@ -25,12 +25,12 @@ path = "../ast"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-errors] [dependencies.leo-errors]
path = "../../leo/errors" path = "../../errors"
version = "1.5.3" version = "1.5.3"
[dependencies.leo-span] [dependencies.leo-span]
path = "../../leo/span" path = "../span"
version = "1.5.3" version = "1.5.3"
[dependencies] [dependencies.indexmap]
indexmap = "1.7.0" version = "1.9"

View File

@ -1,6 +1,6 @@
# leo-core # leo-core
[![Crates.io](https://img.shields.io/crates/v/leo-ast.svg?color=neon)](https://crates.io/crates/leo-ast) [![Crates.io](https://img.shields.io/crates/v/leo-ast.svg?color=neon)](https://crates.io/crates/leo-core)
[![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](../AUTHORS) [![Authors](https://img.shields.io/badge/authors-Aleo-orange.svg)](../AUTHORS)
[![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md)

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: inputs/index.in
*/
function main (x: u32) -> bool {
const y = [aleo1x0rh2cudq93fhukrsce8sgvcphddv4qs0clph64stpg0hstfds9qjvxcg6; 3];
let z = y[x];
return z == y[0];
}

View File

@ -1,17 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file:
- inputs/dummy.in
*/
type Int = u32;
circuit Int {
x: u8;
}
function main(y: bool) -> bool {
return y;
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file:
- inputs/dummy.in
*/
type int = u32;
function int() {}
function main(y: bool) -> bool {
return y;
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file:
- inputs/dummy.in
*/
type int = u32;
const int = 8u8;
function main(y: bool) -> bool {
return y;
}

View File

@ -1,17 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- inputs/basic.in
*/
type int = u32;
function main(x: u32, y: bool) -> bool {
let a: int = x;
let b: int = 2;
let c: int = a + b;
return a == 1u32 && b == 2u32
&& c == 3u32 && y;
}

View File

@ -1,19 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- inputs/basic.in
*/
type int = u32;
type number = int;
function main(x: u32, y: bool) -> bool {
let a: int = x;
let b: number = 2u32;
let c: number = 3;
let d: u32 = a + b + c;
return a == 1u32 && b == 2u32
&& c == 3u32 && d == 6u32 && y;
}

View File

@ -1,25 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- inputs/basic.in
*/
type int = u32;
circuit Foo {
a: u32;
}
circuit Bar {
a: int;
}
function main(x: u32, y: bool) -> bool {
let a: int = x;
let f: Foo = Foo { a };
let b: Bar = Bar { a };
return a == 1u32 && f.a == 1u32
&& b.a == 1u32 && y;
}

View File

@ -1,13 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file:
- inputs/dummy.in
*/
type int = u32;
type int = u8;
function main(y: bool) -> bool {
return y;
}

View File

@ -1,23 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- inputs/dummy.in
*/
type int = u32;
function return_int_triary() -> (int, int, int) {
return (1, 2, 3);
}
function return_int_array() -> [int; 3] {
return [0u32; 3];
}
function main(y: bool) -> bool {
let a: (int, int, int) = return_int_triary();
let b: [int; 3] = return_int_array();
return y;
}

View File

@ -1,6 +0,0 @@
[main]
x: u32 = 1;
y: bool = true;
[registers]
r0: bool = false;

View File

@ -1,5 +0,0 @@
[main]
y: bool = true;
[registers]
r0: bool = false;

View File

@ -1,6 +0,0 @@
[main]
x: u8 = 1;
y: bool = true;
[registers]
r0: bool = false;

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- inputs/basic.in
*/
type x = u32;
function main(x: x, y: bool) -> bool {
return y;
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- inputs/dummy.in
*/
type int = u32;
function main(y: bool) -> bool {
let int: int = 1u32;
return y;
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file:
- inputs/wrong_type_fail.in
*/
type int = u32;
function main(x: u8, y: bool) -> bool {
let a: int = x;
return a == 1u32 && y;
}

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/array_range_access_fail.in
*/
function main (
const x: u32
) {
const y = [1u8; 3];
const z: [u8; 2] = y[..1u32][..x];
}

View File

@ -1,9 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/dummy.in
*/
function main() {
let a = [true; (0)];
}

View File

@ -1,35 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- input/complex_access.in
*/
circuit Circ {
f: u32
}
function main (a: [u8; 8], b: u32, c: [[u8; 3]; 3], d: [(u8, u32); 1], e: [u8; (3, 4)] ) -> bool {
a[0..3][b] = 93;
a[2..6][1] = 87;
a[2..6][1] *= 2;
a[2..3] = [42u8];
a[6..][0] = 43u8;
a[0..1][0..1] = [200];
c[0..2][0] = [1u8; 3];
c[1..][1][1..2][0] = 126;
c[1..][0] = [42, 43, 44];
c[Circ {f: 0}.f..1][0][0] += 2;
d[..1][0].1 = 1;
e[0..][0] = [22; 4];
e[0..][0][0] = 33;
return
a == [200u8, 93, 42, 174, 5, 6, 43, 8]
&& c == [[3u8, 1, 1], [42, 43, 44], [7, 126, 9]]
&& d == [(0u8, 1u32)]
&& e == [[33u8, 22, 22, 22], [0, 0, 0, 0], [0, 0, 0, 0]];
}

View File

@ -1,11 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- input/six_zeros.in
- input/count_to_6.in
*/
function main(a: [u8; (3, 2)]) -> bool {
return a == [0u8; (3, 2)];
}

View File

@ -1,11 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- input/six_zeros.in
- input/count_to_6.in
*/
function main(a: [u8; (3, 2)]) -> bool {
return a == [[1u8, 2], [3, 4], [5, 6]];
}

View File

@ -1,2 +0,0 @@
[constants]
x: u32 = 1u32;

View File

@ -1,9 +0,0 @@
[main]
a: [u8; 8] = [1u8, 2, 3, 4, 5, 6, 7, 8];
b: u32 = 1;
c: [[u8; 3]; 3] = [[1u8, 2, 3], [4, 5, 6], [7, 8, 9]];
d: [(u8, u32); 1] = [(0u8, 0u32)];
e: [u8; (3, 4)] = [0u8; (3, 4)];
[registers]
out: bool = true;

View File

@ -1,5 +0,0 @@
[main]
a: [[u8; 2]; 3] = [[1, 2], [3, 4], [5, 6]];
[registers]
x: bool = false;

View File

@ -1,6 +0,0 @@
[main]
y: bool = true;
n: bool = false;
[registers]
r0: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [0u8; (2, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [[0u8; 2]; 3];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [[0u8; 3]; 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [0u8; (3, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [0u8; (2, 3)];
[registers]
x: bool = false;

View File

@ -1,8 +0,0 @@
[main]
a: [u8; 3] = [1, 1, 1];
[registers]
r: [u8; 3] = [1u8, 1u8, 1u8];
[registers]
x: bool = false;

View File

@ -1,8 +0,0 @@
[main]
a: [u8; 3] = [1, 1, 1]; // doesn't match arr below
[registers]
r: [u8; 3] = [0u8, 0u8, 0u8];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [0; (3, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; 3] = [1, 1, 1];
[registers]
x: bool = false;

View File

@ -1,6 +0,0 @@
[main]
a: [[u8; 2]; 3] = [[0; 2]; 3];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[u8; 2]; 3] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[[u8; 2]; 3]; 4] = [[[0; 2]; 3]; 4];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[[u8; 2]; 3]; 4] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[u8; 2]; 3] = [0; (3, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[u8; 2]; 3] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[[u8; 2]; 3]; 4] = [0; (4, 3, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [[[u8; 2]; 3]; 4] = [0; (2, 3, 4)]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [[0; 2]; 3];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (4, 3, 2)] = [[[0; 2]; 3]; 4];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (4, 3, 2)] = [[[0; 4]; 3]; 2]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [0; (3, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (3, 2)] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (4, 3, 2)] = [0; (4, 3, 2)];
[registers]
x: bool = false;

View File

@ -1,5 +0,0 @@
[main]
a: [u8; (4, 3, 2)] = [0; (2, 3, 4)]; // initializer (incorrectly reversed ordering)
[registers]
x: bool = false;

View File

@ -1,9 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/input_nested_3x2.in
*/
function main(a: [u8; (3, 2)]) -> bool {
return a == [[0u8; 2]; 3];
}

View File

@ -1,9 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/input_nested_3x2_fail.in
*/
function main(a: [u8; (3, 2)]) -> bool {
return a == [[0u8; 2]; 3)]; // This should be written the right way as this test is for the input file.
}

View File

@ -1,9 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/input_tuple_3x2.in
*/
function main(a: [u8; (3, 2)]) -> bool {
return a == [0u8; (3, 2)];
}

View File

@ -1,9 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/input_tuple_3x2_fail.in
*/
function main(a: [u8; (3, 2)]) -> bool {
return a == [0u8; (3, 2)];
}

View File

@ -1,10 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/dummy.in
*/
function main() -> bool {
const arr: [u8; (2, 2)] = [[1u8; 2]; 1]; // incorrect dimensions
return false;
}

View File

@ -1,11 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/dummy.in
*/
function main() -> bool {
const arr: [u8; (2, 2)] = [[1u8, 1u8],
[1u8]]; // incorrect dimensions
return false;
}

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/dummy.in
*/
function main(y: bool) -> bool {
const a: [u8; (2, 2, 2)] = [1u8; (2, 2, 2)];
const b: [u8; (2, 2, 2)] = [[[1u8; 2]; 2]; 2];
return (a == b) == y;
}

View File

@ -1,10 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/dummy.in
*/
function main() -> bool {
const arr: [u8; (2, 2)] = [1u8; (2, 1)]; // incorrect dimensions
return false;
}

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/dummy.in
*/
function main(n: bool) -> bool {
const x = [false; (2, 2)];
const z: bool = x[0][0];
return n == z;
}

View File

@ -1,13 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/dummy.in
*/
// Multidimensional array syntax in leo
function main(y: bool) -> bool {
const a = [[0u32, 0u32], [0u32, 0u32], [0u32, 0u32]]; // inline
const b: [u32; (3, 2)] = [[0; 2]; 3]; // initializer
return (a == b) == y;
}

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Fail
input_file: input/dummy.in
*/
// Multidimensional array syntax in leo
function main(y: bool) -> bool {
const a: [u32; (3, 2)] = [[0; 3]; 2]; // initializer (incorrectly reversed ordering)
return false;
}

View File

@ -1,11 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file:
- input/registers_ones.in
- input/registers_zeros.in
*/
function main(a: [u8; 3]) -> [u8; 3] {
return input.registers.r == a ? [3,2,1] : [1,2,3];
}

View File

@ -1,11 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/three_ones.in
*/
// `{from}..{to}` copies the elements of one array into another exclusively
function main(a: [u8; 3]) -> bool {
const b = [1u8; 4];
return a == b[0..3];
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/dummy.in
*/
function main(y: bool) -> bool {
const arr: [u32; 9] = [0, 1, 2, 3, 4, 5, 6, 7, 8];
const expected: [u32; 2] = [0, 1];
const actual = arr[..2]; // Should produce [0, 1]
return (expected == actual) == y;
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/three_ones.in
*/
// A spread operator `...` copies the elements of one array into another
function main(a: [u8; 3]) -> bool {
const b = [1u8, 1u8];
const c = [1u8, ...b];
const d = [...b, 1u8];
return a == c && d == a;
}

View File

@ -1,10 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/three_ones.in
*/
function main (a: [u8; 3]) -> bool {
let y = a[0..[0u8; 2] == [0u8; 2]? 2u8 : 2u8];
return y == [1u8, 1];
}

View File

@ -1,13 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/dummy.in
*/
// Multidimensional array syntax in leo
function main(y: bool) -> bool {
const a = [[0u32, 0u32], [0u32, 0u32], [0u32, 0u32]]; // inline
const b: [u32; (3, 2)] = [0; (3, 2)]; // initializer
return (a == b) == y;
}

View File

@ -1,9 +0,0 @@
/*
namespace: Compile
expectation: Fail
*/
// Multidimensional array syntax in leo
function main() {
const a: [u32; (3, 2)] = [0; (2, 3)]; // initializer (incorrectly reversed ordering)
}

View File

@ -1,8 +0,0 @@
/*
namespace: Compile
expectation: Fail
*/
function main() {
const a: [u8; -2] = [0u32; 2];
}

View File

@ -1,11 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/input_tuple_3x2.in
*/
function main(a: [[u8; 2]; 3]) -> bool {
const b = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
return a == b;
}

View File

@ -1,14 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/type_tuple_value_nested_4x3x2.in
*/
function main(a: [[[u8; 2]; 3]; 4]) -> bool {
const b = [[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]],
[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]],
[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]],
[[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]]; // inline
return a == b;
}

View File

@ -1,12 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/type_nested_value_nested_3x2.in
*/
function main(a: [[u8; 2]; 3]) -> bool {
const c = [[0u8, 0u8], [0u8, 0u8], [0u8, 0u8]]; // inline
const b: [[u8; 2]; 3] = [[0; 2]; 3]; // initializer
return b == a && a == c;
}

Some files were not shown because too many files have changed in this diff Show More