mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 13:56:58 +03:00
Merge pull request #2348 from AleoHQ/testnet3.3
[Feature] Upgrades for Phase 3.
This commit is contained in:
commit
80005d67e5
620
Cargo.lock
generated
620
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@ -21,7 +21,6 @@ edition = "2021"
|
||||
members = [
|
||||
"compiler/ast",
|
||||
"compiler/compiler",
|
||||
"compiler/core",
|
||||
"compiler/parser",
|
||||
"compiler/passes",
|
||||
"compiler/span",
|
||||
@ -32,10 +31,10 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.dependencies.snarkvm]
|
||||
version = "0.9.15"
|
||||
version = "0.10.2"
|
||||
|
||||
[workspace.dependencies.snarkvm-console]
|
||||
version = "0.9.15"
|
||||
version = "0.10.2"
|
||||
|
||||
[lib]
|
||||
path = "leo/lib.rs"
|
||||
@ -49,9 +48,6 @@ default = [ ]
|
||||
ci_skip = [ "leo-compiler/ci_skip" ]
|
||||
noconfig = [ ]
|
||||
|
||||
[dependencies.aleo]
|
||||
version = "=0.3.6"
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "./compiler/ast"
|
||||
version = "1.6.3"
|
||||
@ -125,7 +121,7 @@ version = "1.0"
|
||||
|
||||
[dependencies.snarkvm]
|
||||
workspace = true
|
||||
features = [ "aleo-cli", "circuit", "console", "parallel" ]
|
||||
features = [ "circuit", "console" ]
|
||||
|
||||
[dependencies.sys-info]
|
||||
version = "0.9.1"
|
||||
|
@ -28,7 +28,7 @@ pub struct AssociatedFunction {
|
||||
/// The static struct member function that is being accessed.
|
||||
pub name: Identifier,
|
||||
/// The arguments passed to the function `name`.
|
||||
pub args: Vec<Expression>,
|
||||
pub arguments: Vec<Expression>,
|
||||
/// The span for the entire expression `Foo::bar()`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
100
compiler/ast/src/functions/core_function.rs
Normal file
100
compiler/ast/src/functions/core_function.rs
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2019-2023 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 leo_span::{sym, Symbol};
|
||||
|
||||
/// A core instruction that maps directly to an AVM bytecode instruction.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum CoreFunction {
|
||||
BHP256Commit,
|
||||
BHP256Hash,
|
||||
BHP512Commit,
|
||||
BHP512Hash,
|
||||
BHP768Commit,
|
||||
BHP768Hash,
|
||||
BHP1024Commit,
|
||||
BHP1024Hash,
|
||||
|
||||
Pedersen64Commit,
|
||||
Pedersen64Hash,
|
||||
Pedersen128Commit,
|
||||
Pedersen128Hash,
|
||||
|
||||
Poseidon2Hash,
|
||||
Poseidon4Hash,
|
||||
Poseidon8Hash,
|
||||
|
||||
MappingGet,
|
||||
MappingGetOrInit,
|
||||
MappingSet,
|
||||
}
|
||||
|
||||
impl CoreFunction {
|
||||
/// Returns a `CoreFunction` from the given module and method symbols.
|
||||
pub fn from_symbols(module: Symbol, function: Symbol) -> Option<Self> {
|
||||
Some(match (module, function) {
|
||||
(sym::BHP256, sym::commit) => Self::BHP256Commit,
|
||||
(sym::BHP256, sym::hash) => Self::BHP256Hash,
|
||||
(sym::BHP512, sym::commit) => Self::BHP512Commit,
|
||||
(sym::BHP512, sym::hash) => Self::BHP512Hash,
|
||||
(sym::BHP768, sym::commit) => Self::BHP768Commit,
|
||||
(sym::BHP768, sym::hash) => Self::BHP768Hash,
|
||||
(sym::BHP1024, sym::commit) => Self::BHP1024Commit,
|
||||
(sym::BHP1024, sym::hash) => Self::BHP1024Hash,
|
||||
|
||||
(sym::Pedersen64, sym::commit) => Self::Pedersen64Commit,
|
||||
(sym::Pedersen64, sym::hash) => Self::Pedersen64Hash,
|
||||
(sym::Pedersen128, sym::commit) => Self::Pedersen128Commit,
|
||||
(sym::Pedersen128, sym::hash) => Self::Pedersen128Hash,
|
||||
|
||||
(sym::Poseidon2, sym::hash) => Self::Poseidon2Hash,
|
||||
(sym::Poseidon4, sym::hash) => Self::Poseidon4Hash,
|
||||
(sym::Poseidon8, sym::hash) => Self::Poseidon8Hash,
|
||||
|
||||
(sym::Mapping, sym::get) => Self::MappingGet,
|
||||
(sym::Mapping, sym::get_or_init) => Self::MappingGetOrInit,
|
||||
(sym::Mapping, sym::set) => Self::MappingSet,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the number of arguments required by the instruction.
|
||||
pub fn num_args(&self) -> usize {
|
||||
match self {
|
||||
Self::BHP256Commit => 2,
|
||||
Self::BHP256Hash => 1,
|
||||
Self::BHP512Commit => 2,
|
||||
Self::BHP512Hash => 1,
|
||||
Self::BHP768Commit => 2,
|
||||
Self::BHP768Hash => 1,
|
||||
Self::BHP1024Commit => 2,
|
||||
Self::BHP1024Hash => 1,
|
||||
|
||||
Self::Pedersen64Commit => 2,
|
||||
Self::Pedersen64Hash => 1,
|
||||
Self::Pedersen128Commit => 2,
|
||||
Self::Pedersen128Hash => 1,
|
||||
|
||||
Self::Poseidon2Hash => 1,
|
||||
Self::Poseidon4Hash => 1,
|
||||
Self::Poseidon8Hash => 1,
|
||||
|
||||
Self::MappingGet => 2,
|
||||
Self::MappingGetOrInit => 3,
|
||||
Self::MappingSet => 3,
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,9 @@
|
||||
pub mod annotation;
|
||||
pub use annotation::*;
|
||||
|
||||
pub mod core_function;
|
||||
pub use core_function::*;
|
||||
|
||||
pub mod variant;
|
||||
pub use variant::*;
|
||||
|
||||
|
@ -20,10 +20,6 @@
|
||||
//! The [`Ast`] type is intended to be parsed and modified by different passes
|
||||
//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`Ast`].
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
extern crate core;
|
||||
|
||||
pub mod access;
|
||||
pub use self::access::*;
|
||||
|
||||
|
@ -75,10 +75,8 @@ pub trait StatementConsumer {
|
||||
Statement::Block(stmt) => self.consume_block(stmt),
|
||||
Statement::Conditional(stmt) => self.consume_conditional(stmt),
|
||||
Statement::Console(stmt) => self.consume_console(stmt),
|
||||
Statement::Decrement(stmt) => self.consume_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.consume_definition(stmt),
|
||||
Statement::Expression(stmt) => self.consume_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.consume_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.consume_iteration(*stmt),
|
||||
Statement::Return(stmt) => self.consume_return(stmt),
|
||||
}
|
||||
@ -94,14 +92,10 @@ pub trait StatementConsumer {
|
||||
|
||||
fn consume_console(&mut self, input: ConsoleStatement) -> Self::Output;
|
||||
|
||||
fn consume_decrement(&mut self, input: DecrementStatement) -> Self::Output;
|
||||
|
||||
fn consume_definition(&mut self, input: DefinitionStatement) -> Self::Output;
|
||||
|
||||
fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output;
|
||||
|
||||
fn consume_increment(&mut self, input: IncrementStatement) -> Self::Output;
|
||||
|
||||
fn consume_iteration(&mut self, input: IterationStatement) -> Self::Output;
|
||||
|
||||
fn consume_return(&mut self, input: ReturnStatement) -> Self::Output;
|
||||
|
@ -47,7 +47,11 @@ pub trait ExpressionReconstructor {
|
||||
AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: function.ty,
|
||||
name: function.name,
|
||||
args: function.args.into_iter().map(|arg| self.reconstruct_expression(arg).0).collect(),
|
||||
arguments: function
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|arg| self.reconstruct_expression(arg).0)
|
||||
.collect(),
|
||||
span: function.span,
|
||||
})
|
||||
}
|
||||
@ -157,10 +161,8 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
}
|
||||
Statement::Conditional(stmt) => self.reconstruct_conditional(stmt),
|
||||
Statement::Console(stmt) => self.reconstruct_console(stmt),
|
||||
Statement::Decrement(stmt) => self.reconstruct_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.reconstruct_definition(stmt),
|
||||
Statement::Expression(stmt) => self.reconstruct_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.reconstruct_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.reconstruct_iteration(*stmt),
|
||||
Statement::Return(stmt) => self.reconstruct_return(stmt),
|
||||
}
|
||||
@ -239,19 +241,6 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Reconstructor should visit this.
|
||||
fn reconstruct_decrement(&mut self, input: DecrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Decrement(DecrementStatement {
|
||||
mapping: input.mapping,
|
||||
amount: input.amount,
|
||||
index: input.index,
|
||||
span: input.span,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Definition(DefinitionStatement {
|
||||
@ -275,19 +264,6 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Reconstructor should visit this.
|
||||
fn reconstruct_increment(&mut self, input: IncrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Increment(IncrementStatement {
|
||||
mapping: input.mapping,
|
||||
index: input.index,
|
||||
amount: input.amount,
|
||||
span: input.span,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn reconstruct_iteration(&mut self, input: IterationStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
(
|
||||
Statement::Iteration(Box::new(IterationStatement {
|
||||
|
@ -44,7 +44,7 @@ pub trait ExpressionVisitor<'a> {
|
||||
fn visit_access(&mut self, input: &'a AccessExpression, additional: &Self::AdditionalInput) -> Self::Output {
|
||||
match input {
|
||||
AccessExpression::AssociatedFunction(function) => {
|
||||
function.args.iter().for_each(|arg| {
|
||||
function.arguments.iter().for_each(|arg| {
|
||||
self.visit_expression(arg, &Default::default());
|
||||
});
|
||||
}
|
||||
@ -122,10 +122,8 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
}
|
||||
@ -173,12 +171,6 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
};
|
||||
}
|
||||
|
||||
fn visit_decrement(&mut self, input: &'a DecrementStatement) {
|
||||
self.visit_expression(&input.amount, &Default::default());
|
||||
self.visit_expression(&input.index, &Default::default());
|
||||
self.visit_identifier(&input.mapping, &Default::default());
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
self.visit_expression(&input.value, &Default::default());
|
||||
}
|
||||
@ -187,12 +179,6 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
self.visit_expression(&input.expression, &Default::default());
|
||||
}
|
||||
|
||||
fn visit_increment(&mut self, input: &'a IncrementStatement) {
|
||||
self.visit_expression(&input.amount, &Default::default());
|
||||
self.visit_expression(&input.index, &Default::default());
|
||||
self.visit_identifier(&input.mapping, &Default::default());
|
||||
}
|
||||
|
||||
fn visit_iteration(&mut self, input: &'a IterationStatement) {
|
||||
self.visit_expression(&input.start, &Default::default());
|
||||
self.visit_expression(&input.stop, &Default::default());
|
||||
|
@ -1,43 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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 core::fmt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A decrement statement `decrement(foo, bar, 1);`.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub struct DecrementStatement {
|
||||
/// The mapping to be modified.
|
||||
pub mapping: Identifier,
|
||||
/// The index of the element to be decremented.
|
||||
pub index: Expression,
|
||||
/// The amount to decrement the element by.
|
||||
pub amount: Expression,
|
||||
/// The span of `decrement(foo, bar, 1)` excluding the semicolon.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for DecrementStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "decrement({}, {}, {});", self.mapping, self.index, self.amount)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(DecrementStatement);
|
@ -1,43 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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 core::fmt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An increment statement `increment(foo, bar, 1);`.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
pub struct IncrementStatement {
|
||||
/// The mapping to be modified.
|
||||
pub mapping: Identifier,
|
||||
/// The index of the element to be incremented.
|
||||
pub index: Expression,
|
||||
/// The amount to increment the element by.
|
||||
pub amount: Expression,
|
||||
/// The span of `increment(foo, bar, 1)` excluding the semicolon.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for IncrementStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "increment({}, {}, {});", self.mapping, self.index, self.amount)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(IncrementStatement);
|
@ -29,18 +29,12 @@ pub use conditional::*;
|
||||
pub mod console;
|
||||
pub use console::*;
|
||||
|
||||
pub mod decrement;
|
||||
pub use decrement::*;
|
||||
|
||||
pub mod definition;
|
||||
pub use definition::*;
|
||||
|
||||
pub mod expression;
|
||||
pub use expression::*;
|
||||
|
||||
pub mod increment;
|
||||
pub use increment::*;
|
||||
|
||||
pub mod iteration;
|
||||
pub use iteration::*;
|
||||
|
||||
@ -67,14 +61,10 @@ pub enum Statement {
|
||||
Conditional(ConditionalStatement),
|
||||
/// A console logging statement.
|
||||
Console(ConsoleStatement),
|
||||
/// A decrement statement.
|
||||
Decrement(DecrementStatement),
|
||||
/// A binding or set of bindings / variables to declare.
|
||||
Definition(DefinitionStatement),
|
||||
/// An expression statement
|
||||
Expression(ExpressionStatement),
|
||||
/// An increment statement.
|
||||
Increment(IncrementStatement),
|
||||
/// A `for` statement.
|
||||
Iteration(Box<IterationStatement>),
|
||||
/// A return statement `return expr;`.
|
||||
@ -96,10 +86,8 @@ impl fmt::Display for Statement {
|
||||
Statement::Block(x) => x.fmt(f),
|
||||
Statement::Conditional(x) => x.fmt(f),
|
||||
Statement::Console(x) => x.fmt(f),
|
||||
Statement::Decrement(x) => x.fmt(f),
|
||||
Statement::Definition(x) => x.fmt(f),
|
||||
Statement::Expression(x) => x.fmt(f),
|
||||
Statement::Increment(x) => x.fmt(f),
|
||||
Statement::Iteration(x) => x.fmt(f),
|
||||
Statement::Return(x) => x.fmt(f),
|
||||
}
|
||||
@ -115,10 +103,8 @@ impl Node for Statement {
|
||||
Block(n) => n.span(),
|
||||
Conditional(n) => n.span(),
|
||||
Console(n) => n.span(),
|
||||
Decrement(n) => n.span(),
|
||||
Definition(n) => n.span(),
|
||||
Expression(n) => n.span(),
|
||||
Increment(n) => n.span(),
|
||||
Iteration(n) => n.span(),
|
||||
Return(n) => n.span(),
|
||||
}
|
||||
@ -132,10 +118,8 @@ impl Node for Statement {
|
||||
Block(n) => n.set_span(span),
|
||||
Conditional(n) => n.set_span(span),
|
||||
Console(n) => n.set_span(span),
|
||||
Decrement(n) => n.set_span(span),
|
||||
Definition(n) => n.set_span(span),
|
||||
Expression(n) => n.set_span(span),
|
||||
Increment(n) => n.set_span(span),
|
||||
Iteration(n) => n.set_span(span),
|
||||
Return(n) => n.set_span(span),
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ default-features = false
|
||||
[dev-dependencies.snarkvm]
|
||||
workspace = true
|
||||
default-features = false
|
||||
features = [ "aleo-cli", "circuit", "console", "parallel" ]
|
||||
features = [ "circuit", "console", ]
|
||||
|
||||
[dev-dependencies.regex]
|
||||
version = "1.7.3"
|
||||
|
@ -50,8 +50,9 @@ impl Namespace for CompileNamespace {
|
||||
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).map_err(|()| buf.0.take().to_string()))
|
||||
create_session_if_not_set_then(|_| {
|
||||
run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string() + &buf.1.take().to_string())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,9 +65,10 @@ struct CompileOutput {
|
||||
pub inlined_ast: String,
|
||||
pub dce_ast: String,
|
||||
pub bytecode: String,
|
||||
pub warnings: String,
|
||||
}
|
||||
|
||||
fn run_test(test: Test, handler: &Handler) -> Result<Value, ()> {
|
||||
fn run_test(test: Test, handler: &Handler, buf: &BufferEmitter) -> Result<Value, ()> {
|
||||
// Check for CWD option:
|
||||
let cwd = get_cwd_option(&test);
|
||||
|
||||
@ -120,6 +122,7 @@ fn run_test(test: Test, handler: &Handler) -> Result<Value, ()> {
|
||||
inlined_ast,
|
||||
dce_ast,
|
||||
bytecode: hash_content(&bytecode),
|
||||
warnings: buf.1.take().to_string(),
|
||||
};
|
||||
|
||||
outputs.push(final_output);
|
||||
|
@ -56,8 +56,9 @@ impl Namespace for ExecuteNamespace {
|
||||
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()))
|
||||
create_session_if_not_set_then(|_| {
|
||||
run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string() + &buf.1.take().to_string())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +72,7 @@ struct ExecuteOutput {
|
||||
pub inlined_ast: String,
|
||||
pub dce_ast: String,
|
||||
pub bytecode: String,
|
||||
pub warnings: String,
|
||||
pub results: BTreeMap<String, Vec<BTreeMap<String, String>>>,
|
||||
}
|
||||
|
||||
@ -127,7 +129,7 @@ fn run_test(test: Test, handler: &Handler, err_buf: &BufferEmitter) -> Result<Va
|
||||
let package = setup_build_directory(&program_name, &bytecode, handler)?;
|
||||
|
||||
// Initialize an rng.
|
||||
let rng = &mut rand::thread_rng();
|
||||
let rng = &mut TestRng::default();
|
||||
|
||||
// Run each test case for each function.
|
||||
for (function_name, function_cases) in all_cases {
|
||||
@ -203,6 +205,7 @@ fn run_test(test: Test, handler: &Handler, err_buf: &BufferEmitter) -> Result<Va
|
||||
inlined_ast,
|
||||
dce_ast,
|
||||
bytecode: hash_content(&bytecode),
|
||||
warnings: err_buf.1.take().to_string(),
|
||||
results,
|
||||
};
|
||||
outputs.push(final_output);
|
||||
|
262
compiler/compiler/tests/finalize.rs
Normal file
262
compiler/compiler/tests/finalize.rs
Normal file
@ -0,0 +1,262 @@
|
||||
// Copyright (C) 2019-2023 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 utilities;
|
||||
use utilities::{buffer_if_err, compile_and_process, get_cwd_option, parse_program, BufferEmitter, Network};
|
||||
|
||||
use crate::utilities::{get_build_options, hash_asts, hash_content, Aleo};
|
||||
|
||||
use leo_errors::emitter::Handler;
|
||||
use leo_span::symbol::create_session_if_not_set_then;
|
||||
use leo_test_framework::{
|
||||
runner::{Namespace, ParseType, Runner},
|
||||
Test,
|
||||
};
|
||||
|
||||
use snarkvm::{console, prelude::*};
|
||||
|
||||
use leo_compiler::{CompilerOptions, OutputOptions};
|
||||
use leo_test_framework::test::TestExpectationMode;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Value;
|
||||
use std::{collections::BTreeMap, fs, path::Path, rc::Rc};
|
||||
|
||||
struct FinalizeNamespace;
|
||||
|
||||
impl Namespace for FinalizeNamespace {
|
||||
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() + &buf.1.take().to_string())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Format this better.
|
||||
#[derive(Deserialize, PartialEq, Eq, Serialize)]
|
||||
struct FinalizeOutput {
|
||||
pub initial_ast: String,
|
||||
pub unrolled_ast: String,
|
||||
pub ssa_ast: String,
|
||||
pub flattened_ast: String,
|
||||
pub inlined_ast: String,
|
||||
pub dce_ast: String,
|
||||
pub bytecode: String,
|
||||
pub warnings: String,
|
||||
pub initial_state: String,
|
||||
pub results: BTreeMap<String, Vec<BTreeMap<String, String>>>,
|
||||
}
|
||||
|
||||
fn run_test(test: Test, handler: &Handler, err_buf: &BufferEmitter) -> Result<Value, ()> {
|
||||
// Check that config expectation is always pass.
|
||||
if test.config.expectation != TestExpectationMode::Pass {
|
||||
buffer_if_err(err_buf, Err("Test expectation must be `Pass` for `Finalize` tests.".to_string()))?;
|
||||
}
|
||||
|
||||
// Check for CWD option:
|
||||
let cwd = get_cwd_option(&test);
|
||||
|
||||
// Extract the compiler build configurations from the config file.
|
||||
let build_options = get_build_options(&test.config);
|
||||
|
||||
let mut outputs = Vec::with_capacity(build_options.len());
|
||||
|
||||
for build in build_options {
|
||||
let compiler_options = CompilerOptions {
|
||||
build,
|
||||
output: OutputOptions {
|
||||
spans_enabled: false,
|
||||
initial_input_ast: true,
|
||||
initial_ast: true,
|
||||
unrolled_ast: true,
|
||||
ssa_ast: true,
|
||||
flattened_ast: true,
|
||||
inlined_ast: true,
|
||||
dce_ast: true,
|
||||
},
|
||||
};
|
||||
|
||||
// Parse the program.
|
||||
let mut parsed =
|
||||
handler.extend_if_error(parse_program(handler, &test.content, cwd.clone(), Some(compiler_options)))?;
|
||||
|
||||
// Compile the program to bytecode.
|
||||
let bytecode = handler.extend_if_error(compile_and_process(&mut parsed))?;
|
||||
println!("Bytecode: {}", bytecode);
|
||||
let program = Program::<Network>::from_str(&bytecode).unwrap();
|
||||
let program_id = program.id();
|
||||
|
||||
// Extract the cases from the test config.
|
||||
let all_cases = test
|
||||
.config
|
||||
.extra
|
||||
.get("cases")
|
||||
.expect("An `Finalize` config must have a `cases` field.")
|
||||
.as_mapping()
|
||||
.unwrap();
|
||||
|
||||
// Extract the initial state from the test config.
|
||||
let initial_state = test
|
||||
.config
|
||||
.extra
|
||||
.get("initial_state")
|
||||
.expect("A `Finalize` config must have a `initial_state` field.")
|
||||
.as_mapping()
|
||||
.unwrap();
|
||||
|
||||
// Initialize the program storage.
|
||||
let store = ProgramStore::<_, ProgramMemory<Network>>::open(None).unwrap();
|
||||
for (mapping_id, key_value_pairs) in initial_state {
|
||||
// Initialize the mapping.
|
||||
let mapping_name = Identifier::from_str(mapping_id.as_str().unwrap()).unwrap();
|
||||
store.initialize_mapping(program_id, &mapping_name).unwrap();
|
||||
|
||||
// Insert the key value pairs.
|
||||
let key_value_pairs = key_value_pairs.as_sequence().unwrap();
|
||||
for pair in key_value_pairs {
|
||||
let pair = pair.as_sequence().unwrap();
|
||||
assert!(pair.len() == 2);
|
||||
store
|
||||
.insert_key_value(
|
||||
program_id,
|
||||
&mapping_name,
|
||||
Plaintext::<Network>::from_str(pair[0].as_str().unwrap()).unwrap(),
|
||||
console::program::Value::<Network>::from_str(pair[1].as_str().unwrap()).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize a process.
|
||||
let mut process = Process::load().unwrap();
|
||||
process.add_program(&program).unwrap();
|
||||
|
||||
// Initialize an rng.
|
||||
let rng = &mut TestRng::default();
|
||||
|
||||
// Initialize a private key.
|
||||
let private_key = PrivateKey::<Network>::new(rng).unwrap();
|
||||
|
||||
// Initialize a map for the expected results.
|
||||
let mut results = BTreeMap::new();
|
||||
|
||||
// Run each test case for each function.
|
||||
for (function_name, function_cases) in all_cases {
|
||||
let function_name = Identifier::from_str(function_name.as_str().unwrap()).unwrap();
|
||||
let cases = function_cases.as_sequence().unwrap();
|
||||
let mut function_results = Vec::with_capacity(cases.len());
|
||||
|
||||
for case in cases {
|
||||
let case = case.as_mapping().unwrap();
|
||||
let inputs: Vec<_> = case
|
||||
.get(&Value::from("input"))
|
||||
.unwrap()
|
||||
.as_sequence()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|input| console::program::Value::<Network>::from_str(input.as_str().unwrap()).unwrap())
|
||||
.collect();
|
||||
let input_string = format!("[{}]", inputs.iter().map(|input| input.to_string()).join(", "));
|
||||
|
||||
// Authorize the function call.
|
||||
let authorization =
|
||||
process.authorize::<Aleo, _>(&private_key, program_id, function_name, inputs.iter(), rng).unwrap();
|
||||
// Execute the function call.
|
||||
let (response, execution, _, _) = process.execute::<Aleo, _>(authorization, rng).unwrap();
|
||||
// Finalize the function call.
|
||||
let finalize_output_string = match process.finalize_execution(&store, &execution) {
|
||||
Ok(_) => "Finalize was successful.".to_string(),
|
||||
Err(err) => format!("SnarkVMError({err})"),
|
||||
};
|
||||
|
||||
// TODO: Add support for custom config like custom private keys.
|
||||
// Execute the program and get the outputs.
|
||||
let execute_output = format!(
|
||||
"[{}]",
|
||||
response
|
||||
.outputs()
|
||||
.iter()
|
||||
.map(|output| {
|
||||
match output {
|
||||
// Remove the `_nonce` from the record string.
|
||||
console::program::Value::Record(record) => {
|
||||
let pattern = Regex::new(r"_nonce: \d+group.public").unwrap();
|
||||
pattern.replace(&record.to_string(), "").to_string()
|
||||
}
|
||||
_ => output.to_string(),
|
||||
}
|
||||
})
|
||||
.join(", ")
|
||||
);
|
||||
|
||||
// Store the inputs and outputs in a map.
|
||||
let mut result = BTreeMap::new();
|
||||
result.insert("input".to_string(), input_string);
|
||||
result.insert("execute_output".to_string(), execute_output);
|
||||
result.insert("finalize_output".to_string(), finalize_output_string);
|
||||
|
||||
// Add the hashes of the inputs and outputs to the function results.
|
||||
function_results.push(result);
|
||||
}
|
||||
results.insert(function_name.to_string(), function_results);
|
||||
}
|
||||
|
||||
// Hash the ast files.
|
||||
let (initial_ast, unrolled_ast, ssa_ast, flattened_ast, inlined_ast, dce_ast) = hash_asts();
|
||||
|
||||
// Clean up the output directory.
|
||||
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 = FinalizeOutput {
|
||||
initial_ast,
|
||||
unrolled_ast,
|
||||
ssa_ast,
|
||||
flattened_ast,
|
||||
inlined_ast,
|
||||
dce_ast,
|
||||
bytecode: hash_content(&bytecode),
|
||||
warnings: err_buf.1.take().to_string(),
|
||||
initial_state: hash_content(&serde_yaml::to_string(&initial_state).unwrap()),
|
||||
results,
|
||||
};
|
||||
outputs.push(final_output)
|
||||
}
|
||||
Ok(serde_yaml::to_value(outputs).expect("serialization failed"))
|
||||
}
|
||||
|
||||
struct TestRunner;
|
||||
|
||||
impl Runner for TestRunner {
|
||||
fn resolve_namespace(&self, name: &str) -> Option<Box<dyn Namespace>> {
|
||||
Some(match name {
|
||||
"Finalize" => Box::new(FinalizeNamespace),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn finalize_tests() {
|
||||
leo_test_framework::run_tests(&TestRunner, "finalize");
|
||||
}
|
@ -30,6 +30,7 @@ use leo_test_framework::test::TestConfig;
|
||||
use snarkvm::{file::Manifest, package::Package};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fmt,
|
||||
fs,
|
||||
fs::File,
|
||||
path::{Path, PathBuf},
|
||||
@ -92,6 +93,7 @@ pub fn get_build_options(test_config: &TestConfig) -> Vec<BuildOptions> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn setup_build_directory(program_name: &str, bytecode: &String, handler: &Handler) -> Result<Package<Network>, ()> {
|
||||
// Initialize a temporary directory.
|
||||
let directory = temp_dir();
|
||||
@ -195,6 +197,7 @@ pub 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)))
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn temp_dir() -> PathBuf {
|
||||
tempfile::tempdir().expect("Failed to open temporary directory").into_path()
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
[package]
|
||||
name = "leo-core"
|
||||
version = "1.6.3"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
description = "Core library functions for the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
repository = "https://github.com/AleoHQ/leo"
|
||||
keywords = [
|
||||
"aleo",
|
||||
"cryptography",
|
||||
"leo",
|
||||
"programming-language",
|
||||
"zero-knowledge"
|
||||
]
|
||||
categories = [ "compilers", "cryptography", "web-programming" ]
|
||||
include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
|
||||
license = "GPL-3.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "../ast"
|
||||
version = "1.6.3"
|
||||
|
||||
[dependencies.leo-errors]
|
||||
path = "../../errors"
|
||||
version = "1.6.3"
|
||||
|
||||
[dependencies.leo-span]
|
||||
path = "../span"
|
||||
version = "1.6.3"
|
@ -1,596 +0,0 @@
|
||||
GNU General Public License
|
||||
==========================
|
||||
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright © 2007 Free Software Foundation, Inc. <<https://fsf.org/>>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
|
||||
## Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for software and other
|
||||
kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed to take away
|
||||
your freedom to share and change the works. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change all versions of a
|
||||
program--to make sure it remains free software for all its users. We, the Free
|
||||
Software Foundation, use the GNU General Public License for most of our software; it
|
||||
applies also to any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our General
|
||||
Public Licenses are designed to make sure that you have the freedom to distribute
|
||||
copies of free software (and charge for them if you wish), that you receive source
|
||||
code or can get it if you want it, that you can change the software or use pieces of
|
||||
it in new free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you these rights or
|
||||
asking you to surrender the rights. Therefore, you have certain responsibilities if
|
||||
you distribute copies of the software, or if you modify it: responsibilities to
|
||||
respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee,
|
||||
you must pass on to the recipients the same freedoms that you received. You must make
|
||||
sure that they, too, receive or can get the source code. And you must show them these
|
||||
terms so they know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps: **(1)** assert
|
||||
copyright on the software, and **(2)** offer you this License giving you legal permission
|
||||
to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains that there is
|
||||
no warranty for this free software. For both users' and authors' sake, the GPL
|
||||
requires that modified versions be marked as changed, so that their problems will not
|
||||
be attributed erroneously to authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run modified versions of
|
||||
the software inside them, although the manufacturer can do so. This is fundamentally
|
||||
incompatible with the aim of protecting users' freedom to change the software. The
|
||||
systematic pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we have designed
|
||||
this version of the GPL to prohibit the practice for those products. If such problems
|
||||
arise substantially in other domains, we stand ready to extend this provision to
|
||||
those domains in future versions of the GPL, as needed to protect the freedom of
|
||||
users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents. States should
|
||||
not allow patents to restrict development and use of software on general-purpose
|
||||
computers, but in those that do, we wish to avoid the special danger that patents
|
||||
applied to a free program could make it effectively proprietary. To prevent this, the
|
||||
GPL assures that patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification follow.
|
||||
|
||||
## TERMS AND CONDITIONS
|
||||
|
||||
### 0. Definitions
|
||||
|
||||
“This License” refers to version 3 of the GNU General Public License.
|
||||
|
||||
“Copyright” also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
“The Program” refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as “you”. “Licensees” and
|
||||
“recipients” may be individuals or organizations.
|
||||
|
||||
To “modify” a work means to copy from or adapt all or part of the work in
|
||||
a fashion requiring copyright permission, other than the making of an exact copy. The
|
||||
resulting work is called a “modified version” of the earlier work or a
|
||||
work “based on” the earlier work.
|
||||
|
||||
A “covered work” means either the unmodified Program or a work based on
|
||||
the Program.
|
||||
|
||||
To “propagate” a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for infringement under
|
||||
applicable copyright law, except executing it on a computer or modifying a private
|
||||
copy. Propagation includes copying, distribution (with or without modification),
|
||||
making available to the public, and in some countries other activities as well.
|
||||
|
||||
To “convey” a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through a computer
|
||||
network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays “Appropriate Legal Notices” to the
|
||||
extent that it includes a convenient and prominently visible feature that **(1)**
|
||||
displays an appropriate copyright notice, and **(2)** tells the user that there is no
|
||||
warranty for the work (except to the extent that warranties are provided), that
|
||||
licensees may convey the work under this License, and how to view a copy of this
|
||||
License. If the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
### 1. Source Code
|
||||
|
||||
The “source code” for a work means the preferred form of the work for
|
||||
making modifications to it. “Object code” means any non-source form of a
|
||||
work.
|
||||
|
||||
A “Standard Interface” means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of interfaces
|
||||
specified for a particular programming language, one that is widely used among
|
||||
developers working in that language.
|
||||
|
||||
The “System Libraries” of an executable work include anything, other than
|
||||
the work as a whole, that **(a)** is included in the normal form of packaging a Major
|
||||
Component, but which is not part of that Major Component, and **(b)** serves only to
|
||||
enable use of the work with that Major Component, or to implement a Standard
|
||||
Interface for which an implementation is available to the public in source code form.
|
||||
A “Major Component”, in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system (if any) on which
|
||||
the executable work runs, or a compiler used to produce the work, or an object code
|
||||
interpreter used to run it.
|
||||
|
||||
The “Corresponding Source” for a work in object code form means all the
|
||||
source code needed to generate, install, and (for an executable work) run the object
|
||||
code and to modify the work, including scripts to control those activities. However,
|
||||
it does not include the work's System Libraries, or general-purpose tools or
|
||||
generally available free programs which are used unmodified in performing those
|
||||
activities but which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for the work, and
|
||||
the source code for shared libraries and dynamically linked subprograms that the work
|
||||
is specifically designed to require, such as by intimate data communication or
|
||||
control flow between those subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users can regenerate
|
||||
automatically from other parts of the Corresponding Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that same work.
|
||||
|
||||
### 2. Basic Permissions
|
||||
|
||||
All rights granted under this License are granted for the term of copyright on the
|
||||
Program, and are irrevocable provided the stated conditions are met. This License
|
||||
explicitly affirms your unlimited permission to run the unmodified Program. The
|
||||
output from running a covered work is covered by this License only if the output,
|
||||
given its content, constitutes a covered work. This License acknowledges your rights
|
||||
of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not convey, without
|
||||
conditions so long as your license otherwise remains in force. You may convey covered
|
||||
works to others for the sole purpose of having them make modifications exclusively
|
||||
for you, or provide you with facilities for running those works, provided that you
|
||||
comply with the terms of this License in conveying all material for which you do not
|
||||
control copyright. Those thus making or running the covered works for you must do so
|
||||
exclusively on your behalf, under your direction and control, on terms that prohibit
|
||||
them from making any copies of your copyrighted material outside their relationship
|
||||
with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under the conditions
|
||||
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
|
||||
|
||||
### 3. Protecting Users' Legal Rights From Anti-Circumvention Law
|
||||
|
||||
No covered work shall be deemed part of an effective technological measure under any
|
||||
applicable law fulfilling obligations under article 11 of the WIPO copyright treaty
|
||||
adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention
|
||||
of such measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid circumvention of
|
||||
technological measures to the extent such circumvention is effected by exercising
|
||||
rights under this License with respect to the covered work, and you disclaim any
|
||||
intention to limit operation or modification of the work as a means of enforcing,
|
||||
against the work's users, your or third parties' legal rights to forbid circumvention
|
||||
of technological measures.
|
||||
|
||||
### 4. Conveying Verbatim Copies
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you receive it, in any
|
||||
medium, provided that you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice; keep intact all notices stating that this License and
|
||||
any non-permissive terms added in accord with section 7 apply to the code; keep
|
||||
intact all notices of the absence of any warranty; and give all recipients a copy of
|
||||
this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey, and you may offer
|
||||
support or warranty protection for a fee.
|
||||
|
||||
### 5. Conveying Modified Source Versions
|
||||
|
||||
You may convey a work based on the Program, or the modifications to produce it from
|
||||
the Program, in the form of source code under the terms of section 4, provided that
|
||||
you also meet all of these conditions:
|
||||
|
||||
* **a)** The work must carry prominent notices stating that you modified it, and giving a
|
||||
relevant date.
|
||||
* **b)** The work must carry prominent notices stating that it is released under this
|
||||
License and any conditions added under section 7. This requirement modifies the
|
||||
requirement in section 4 to “keep intact all notices”.
|
||||
* **c)** You must license the entire work, as a whole, under this License to anyone who
|
||||
comes into possession of a copy. This License will therefore apply, along with any
|
||||
applicable section 7 additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no permission to license the
|
||||
work in any other way, but it does not invalidate such permission if you have
|
||||
separately received it.
|
||||
* **d)** If the work has interactive user interfaces, each must display Appropriate Legal
|
||||
Notices; however, if the Program has interactive interfaces that do not display
|
||||
Appropriate Legal Notices, your work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent works, which are
|
||||
not by their nature extensions of the covered work, and which are not combined with
|
||||
it such as to form a larger program, in or on a volume of a storage or distribution
|
||||
medium, is called an “aggregate” if the compilation and its resulting
|
||||
copyright are not used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work in an aggregate
|
||||
does not cause this License to apply to the other parts of the aggregate.
|
||||
|
||||
### 6. Conveying Non-Source Forms
|
||||
|
||||
You may convey a covered work in object code form under the terms of sections 4 and
|
||||
5, provided that you also convey the machine-readable Corresponding Source under the
|
||||
terms of this License, in one of these ways:
|
||||
|
||||
* **a)** Convey the object code in, or embodied in, a physical product (including a
|
||||
physical distribution medium), accompanied by the Corresponding Source fixed on a
|
||||
durable physical medium customarily used for software interchange.
|
||||
* **b)** Convey the object code in, or embodied in, a physical product (including a
|
||||
physical distribution medium), accompanied by a written offer, valid for at least
|
||||
three years and valid for as long as you offer spare parts or customer support for
|
||||
that product model, to give anyone who possesses the object code either **(1)** a copy of
|
||||
the Corresponding Source for all the software in the product that is covered by this
|
||||
License, on a durable physical medium customarily used for software interchange, for
|
||||
a price no more than your reasonable cost of physically performing this conveying of
|
||||
source, or **(2)** access to copy the Corresponding Source from a network server at no
|
||||
charge.
|
||||
* **c)** Convey individual copies of the object code with a copy of the written offer to
|
||||
provide the Corresponding Source. This alternative is allowed only occasionally and
|
||||
noncommercially, and only if you received the object code with such an offer, in
|
||||
accord with subsection 6b.
|
||||
* **d)** Convey the object code by offering access from a designated place (gratis or for
|
||||
a charge), and offer equivalent access to the Corresponding Source in the same way
|
||||
through the same place at no further charge. You need not require recipients to copy
|
||||
the Corresponding Source along with the object code. If the place to copy the object
|
||||
code is a network server, the Corresponding Source may be on a different server
|
||||
(operated by you or a third party) that supports equivalent copying facilities,
|
||||
provided you maintain clear directions next to the object code saying where to find
|
||||
the Corresponding Source. Regardless of what server hosts the Corresponding Source,
|
||||
you remain obligated to ensure that it is available for as long as needed to satisfy
|
||||
these requirements.
|
||||
* **e)** Convey the object code using peer-to-peer transmission, provided you inform
|
||||
other peers where the object code and Corresponding Source of the work are being
|
||||
offered to the general public at no charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded from the
|
||||
Corresponding Source as a System Library, need not be included in conveying the
|
||||
object code work.
|
||||
|
||||
A “User Product” is either **(1)** a “consumer product”, which
|
||||
means any tangible personal property which is normally used for personal, family, or
|
||||
household purposes, or **(2)** anything designed or sold for incorporation into a
|
||||
dwelling. In determining whether a product is a consumer product, doubtful cases
|
||||
shall be resolved in favor of coverage. For a particular product received by a
|
||||
particular user, “normally used” refers to a typical or common use of
|
||||
that class of product, regardless of the status of the particular user or of the way
|
||||
in which the particular user actually uses, or expects or is expected to use, the
|
||||
product. A product is a consumer product regardless of whether the product has
|
||||
substantial commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
“Installation Information” for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install and execute
|
||||
modified versions of a covered work in that User Product from a modified version of
|
||||
its Corresponding Source. The information must suffice to ensure that the continued
|
||||
functioning of the modified object code is in no case prevented or interfered with
|
||||
solely because modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or specifically for
|
||||
use in, a User Product, and the conveying occurs as part of a transaction in which
|
||||
the right of possession and use of the User Product is transferred to the recipient
|
||||
in perpetuity or for a fixed term (regardless of how the transaction is
|
||||
characterized), the Corresponding Source conveyed under this section must be
|
||||
accompanied by the Installation Information. But this requirement does not apply if
|
||||
neither you nor any third party retains the ability to install modified object code
|
||||
on the User Product (for example, the work has been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a requirement to
|
||||
continue to provide support service, warranty, or updates for a work that has been
|
||||
modified or installed by the recipient, or for the User Product in which it has been
|
||||
modified or installed. Access to a network may be denied when the modification itself
|
||||
materially and adversely affects the operation of the network or violates the rules
|
||||
and protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with
|
||||
this section must be in a format that is publicly documented (and with an
|
||||
implementation available to the public in source code form), and must require no
|
||||
special password or key for unpacking, reading or copying.
|
||||
|
||||
### 7. Additional Terms
|
||||
|
||||
“Additional permissions” are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions. Additional
|
||||
permissions that are applicable to the entire Program shall be treated as though they
|
||||
were included in this License, to the extent that they are valid under applicable
|
||||
law. If additional permissions apply only to part of the Program, that part may be
|
||||
used separately under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option remove any
|
||||
additional permissions from that copy, or from any part of it. (Additional
|
||||
permissions may be written to require their own removal in certain cases when you
|
||||
modify the work.) You may place additional permissions on material, added by you to a
|
||||
covered work, for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you add to a
|
||||
covered work, you may (if authorized by the copyright holders of that material)
|
||||
supplement the terms of this License with terms:
|
||||
|
||||
* **a)** Disclaiming warranty or limiting liability differently from the terms of
|
||||
sections 15 and 16 of this License; or
|
||||
* **b)** Requiring preservation of specified reasonable legal notices or author
|
||||
attributions in that material or in the Appropriate Legal Notices displayed by works
|
||||
containing it; or
|
||||
* **c)** Prohibiting misrepresentation of the origin of that material, or requiring that
|
||||
modified versions of such material be marked in reasonable ways as different from the
|
||||
original version; or
|
||||
* **d)** Limiting the use for publicity purposes of names of licensors or authors of the
|
||||
material; or
|
||||
* **e)** Declining to grant rights under trademark law for use of some trade names,
|
||||
trademarks, or service marks; or
|
||||
* **f)** Requiring indemnification of licensors and authors of that material by anyone
|
||||
who conveys the material (or modified versions of it) with contractual assumptions of
|
||||
liability to the recipient, for any liability that these contractual assumptions
|
||||
directly impose on those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered “further
|
||||
restrictions” within the meaning of section 10. If the Program as you received
|
||||
it, or any part of it, contains a notice stating that it is governed by this License
|
||||
along with a term that is a further restriction, you may remove that term. If a
|
||||
license document contains a further restriction but permits relicensing or conveying
|
||||
under this License, you may add to a covered work material governed by the terms of
|
||||
that license document, provided that the further restriction does not survive such
|
||||
relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you must place, in
|
||||
the relevant source files, a statement of the additional terms that apply to those
|
||||
files, or a notice indicating where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the form of a
|
||||
separately written license, or stated as exceptions; the above requirements apply
|
||||
either way.
|
||||
|
||||
### 8. Termination
|
||||
|
||||
You may not propagate or modify a covered work except as expressly provided under
|
||||
this License. Any attempt otherwise to propagate or modify it is void, and will
|
||||
automatically terminate your rights under this License (including any patent licenses
|
||||
granted under the third paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your license from a
|
||||
particular copyright holder is reinstated **(a)** provisionally, unless and until the
|
||||
copyright holder explicitly and finally terminates your license, and **(b)** permanently,
|
||||
if the copyright holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently
|
||||
if the copyright holder notifies you of the violation by some reasonable means, this
|
||||
is the first time you have received notice of violation of this License (for any
|
||||
work) from that copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the licenses of
|
||||
parties who have received copies or rights from you under this License. If your
|
||||
rights have been terminated and not permanently reinstated, you do not qualify to
|
||||
receive new licenses for the same material under section 10.
|
||||
|
||||
### 9. Acceptance Not Required for Having Copies
|
||||
|
||||
You are not required to accept this License in order to receive or run a copy of the
|
||||
Program. Ancillary propagation of a covered work occurring solely as a consequence of
|
||||
using peer-to-peer transmission to receive a copy likewise does not require
|
||||
acceptance. However, nothing other than this License grants you permission to
|
||||
propagate or modify any covered work. These actions infringe copyright if you do not
|
||||
accept this License. Therefore, by modifying or propagating a covered work, you
|
||||
indicate your acceptance of this License to do so.
|
||||
|
||||
### 10. Automatic Licensing of Downstream Recipients
|
||||
|
||||
Each time you convey a covered work, the recipient automatically receives a license
|
||||
from the original licensors, to run, modify and propagate that work, subject to this
|
||||
License. You are not responsible for enforcing compliance by third parties with this
|
||||
License.
|
||||
|
||||
An “entity transaction” is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an organization, or
|
||||
merging organizations. If propagation of a covered work results from an entity
|
||||
transaction, each party to that transaction who receives a copy of the work also
|
||||
receives whatever licenses to the work the party's predecessor in interest had or
|
||||
could give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if the predecessor
|
||||
has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the rights granted or
|
||||
affirmed under this License. For example, you may not impose a license fee, royalty,
|
||||
or other charge for exercise of rights granted under this License, and you may not
|
||||
initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that any patent claim is infringed by making, using, selling, offering for sale, or
|
||||
importing the Program or any portion of it.
|
||||
|
||||
### 11. Patents
|
||||
|
||||
A “contributor” is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The work thus
|
||||
licensed is called the contributor's “contributor version”.
|
||||
|
||||
A contributor's “essential patent claims” are all patent claims owned or
|
||||
controlled by the contributor, whether already acquired or hereafter acquired, that
|
||||
would be infringed by some manner, permitted by this License, of making, using, or
|
||||
selling its contributor version, but do not include claims that would be infringed
|
||||
only as a consequence of further modification of the contributor version. For
|
||||
purposes of this definition, “control” includes the right to grant patent
|
||||
sublicenses in a manner consistent with the requirements of this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license
|
||||
under the contributor's essential patent claims, to make, use, sell, offer for sale,
|
||||
import and otherwise run, modify and propagate the contents of its contributor
|
||||
version.
|
||||
|
||||
In the following three paragraphs, a “patent license” is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent (such as an
|
||||
express permission to practice a patent or covenant not to sue for patent
|
||||
infringement). To “grant” such a patent license to a party means to make
|
||||
such an agreement or commitment not to enforce a patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license, and the
|
||||
Corresponding Source of the work is not available for anyone to copy, free of charge
|
||||
and under the terms of this License, through a publicly available network server or
|
||||
other readily accessible means, then you must either **(1)** cause the Corresponding
|
||||
Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or **(3)** arrange, in a manner consistent with
|
||||
the requirements of this License, to extend the patent license to downstream
|
||||
recipients. “Knowingly relying” means you have actual knowledge that, but
|
||||
for the patent license, your conveying the covered work in a country, or your
|
||||
recipient's use of the covered work in a country, would infringe one or more
|
||||
identifiable patents in that country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you
|
||||
convey, or propagate by procuring conveyance of, a covered work, and grant a patent
|
||||
license to some of the parties receiving the covered work authorizing them to use,
|
||||
propagate, modify or convey a specific copy of the covered work, then the patent
|
||||
license you grant is automatically extended to all recipients of the covered work and
|
||||
works based on it.
|
||||
|
||||
A patent license is “discriminatory” if it does not include within the
|
||||
scope of its coverage, prohibits the exercise of, or is conditioned on the
|
||||
non-exercise of one or more of the rights that are specifically granted under this
|
||||
License. You may not convey a covered work if you are a party to an arrangement with
|
||||
a third party that is in the business of distributing software, under which you make
|
||||
payment to the third party based on the extent of your activity of conveying the
|
||||
work, and under which the third party grants, to any of the parties who would receive
|
||||
the covered work from you, a discriminatory patent license **(a)** in connection with
|
||||
copies of the covered work conveyed by you (or copies made from those copies), or **(b)**
|
||||
primarily for and in connection with specific products or compilations that contain
|
||||
the covered work, unless you entered into that arrangement, or that patent license
|
||||
was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting any implied
|
||||
license or other defenses to infringement that may otherwise be available to you
|
||||
under applicable patent law.
|
||||
|
||||
### 12. No Surrender of Others' Freedom
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or otherwise)
|
||||
that contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot convey a covered work so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not convey it at all. For example, if you
|
||||
agree to terms that obligate you to collect a royalty for further conveying from
|
||||
those to whom you convey the Program, the only way you could satisfy both those terms
|
||||
and this License would be to refrain entirely from conveying the Program.
|
||||
|
||||
### 13. Use with the GNU Affero General Public License
|
||||
|
||||
Notwithstanding any other provision of this License, you have permission to link or
|
||||
combine any covered work with a work licensed under version 3 of the GNU Affero
|
||||
General Public License into a single combined work, and to convey the resulting work.
|
||||
The terms of this License will continue to apply to the part which is the covered
|
||||
work, but the special requirements of the GNU Affero General Public License, section
|
||||
13, concerning interaction through a network will apply to the combination as such.
|
||||
|
||||
### 14. Revised Versions of this License
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU
|
||||
General Public License from time to time. Such new versions will be similar in spirit
|
||||
to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies that
|
||||
a certain numbered version of the GNU General Public License “or any later
|
||||
version” applies to it, you have the option of following the terms and
|
||||
conditions either of that numbered version or of any later version published by the
|
||||
Free Software Foundation. If the Program does not specify a version number of the GNU
|
||||
General Public License, you may choose any version ever published by the Free
|
||||
Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU
|
||||
General Public License can be used, that proxy's public statement of acceptance of a
|
||||
version permanently authorizes you to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different permissions. However, no
|
||||
additional obligations are imposed on any author or copyright holder as a result of
|
||||
your choosing to follow a later version.
|
||||
|
||||
### 15. Disclaimer of Warranty
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
|
||||
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
### 16. Limitation of Liability
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
|
||||
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
|
||||
PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
||||
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE
|
||||
OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE
|
||||
WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
### 17. Interpretation of Sections 15 and 16
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided above cannot be
|
||||
given local legal effect according to their terms, reviewing courts shall apply local
|
||||
law that most closely approximates an absolute waiver of all civil liability in
|
||||
connection with the Program, unless a warranty or assumption of liability accompanies
|
||||
a copy of the Program in return for a fee.
|
||||
|
||||
_END OF TERMS AND CONDITIONS_
|
||||
|
||||
## How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest possible use to
|
||||
the public, the best way to achieve this is to make it free software which everyone
|
||||
can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to attach them
|
||||
to the start of each source file to most effectively state the exclusion of warranty;
|
||||
and each file should have at least the “copyright” line and a pointer to
|
||||
where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type 'show c' for details.
|
||||
|
||||
The hypothetical commands `show w` and `show c` should show the appropriate parts of
|
||||
the General Public License. Of course, your program's commands might be different;
|
||||
for a GUI interface, you would use an “about box”.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school, if any, to
|
||||
sign a “copyright disclaimer” for the program, if necessary. For more
|
||||
information on this, and how to apply and follow the GNU GPL, see
|
||||
<<http://www.gnu.org/licenses/>>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may consider it
|
||||
more useful to permit linking proprietary applications with the library. If this is
|
||||
what you want to do, use the GNU Lesser General Public License instead of this
|
||||
License. But first, please read
|
||||
<<http://www.gnu.org/philosophy/why-not-lgpl.html>>.
|
@ -1,5 +0,0 @@
|
||||
# leo-core
|
||||
|
||||
[![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)
|
||||
[![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md)
|
@ -1,146 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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::algorithms::CoreFunction;
|
||||
use leo_ast::Type;
|
||||
|
||||
pub struct BHP256Hash;
|
||||
|
||||
impl CoreFunction for BHP256Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP256Commit;
|
||||
|
||||
impl CoreFunction for BHP256Commit {
|
||||
const NUM_ARGS: usize = 2;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn second_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Scalar)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP512Hash;
|
||||
|
||||
impl CoreFunction for BHP512Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP512Commit;
|
||||
|
||||
impl CoreFunction for BHP512Commit {
|
||||
const NUM_ARGS: usize = 2;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn second_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Scalar)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP768Hash;
|
||||
|
||||
impl CoreFunction for BHP768Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP768Commit;
|
||||
|
||||
impl CoreFunction for BHP768Commit {
|
||||
const NUM_ARGS: usize = 2;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn second_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Scalar)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP1024Hash;
|
||||
|
||||
impl CoreFunction for BHP1024Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BHP1024Commit;
|
||||
|
||||
impl CoreFunction for BHP1024Commit {
|
||||
const NUM_ARGS: usize = 2;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn second_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Scalar)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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 bhp;
|
||||
pub use bhp::*;
|
||||
|
||||
mod pedersen;
|
||||
pub use pedersen::*;
|
||||
|
||||
mod poseidon;
|
||||
pub use poseidon::*;
|
||||
|
||||
use leo_ast::Type;
|
||||
use leo_span::{sym, Symbol};
|
||||
|
||||
/// A core instruction that maps directly to an AVM bytecode instruction.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum CoreInstruction {
|
||||
BHP256Commit,
|
||||
BHP256Hash,
|
||||
BHP512Commit,
|
||||
BHP512Hash,
|
||||
BHP768Commit,
|
||||
BHP768Hash,
|
||||
BHP1024Commit,
|
||||
BHP1024Hash,
|
||||
|
||||
Pedersen64Commit,
|
||||
Pedersen64Hash,
|
||||
Pedersen128Commit,
|
||||
Pedersen128Hash,
|
||||
|
||||
Poseidon2Hash,
|
||||
Poseidon4Hash,
|
||||
Poseidon8Hash,
|
||||
}
|
||||
|
||||
impl CoreInstruction {
|
||||
/// Returns a `CoreInstruction` from the given module and method symbols.
|
||||
pub fn from_symbols(module: Symbol, function: Symbol) -> Option<Self> {
|
||||
Some(match (module, function) {
|
||||
(sym::BHP256, sym::commit) => Self::BHP256Commit,
|
||||
(sym::BHP256, sym::hash) => Self::BHP256Hash,
|
||||
(sym::BHP512, sym::commit) => Self::BHP512Commit,
|
||||
(sym::BHP512, sym::hash) => Self::BHP512Hash,
|
||||
(sym::BHP768, sym::commit) => Self::BHP768Commit,
|
||||
(sym::BHP768, sym::hash) => Self::BHP768Hash,
|
||||
(sym::BHP1024, sym::commit) => Self::BHP1024Commit,
|
||||
(sym::BHP1024, sym::hash) => Self::BHP1024Hash,
|
||||
|
||||
(sym::Pedersen64, sym::commit) => Self::Pedersen64Commit,
|
||||
(sym::Pedersen64, sym::hash) => Self::Pedersen64Hash,
|
||||
(sym::Pedersen128, sym::commit) => Self::Pedersen128Commit,
|
||||
(sym::Pedersen128, sym::hash) => Self::Pedersen128Hash,
|
||||
|
||||
(sym::Poseidon2, sym::hash) => Self::Poseidon2Hash,
|
||||
(sym::Poseidon4, sym::hash) => Self::Poseidon4Hash,
|
||||
(sym::Poseidon8, sym::hash) => Self::Poseidon8Hash,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the number of arguments required by the instruction.
|
||||
pub fn num_args(&self) -> usize {
|
||||
match self {
|
||||
Self::BHP256Commit => BHP256Commit::NUM_ARGS,
|
||||
Self::BHP256Hash => BHP256Hash::NUM_ARGS,
|
||||
Self::BHP512Commit => BHP512Commit::NUM_ARGS,
|
||||
Self::BHP512Hash => BHP512Hash::NUM_ARGS,
|
||||
Self::BHP768Commit => BHP768Commit::NUM_ARGS,
|
||||
Self::BHP768Hash => BHP768Hash::NUM_ARGS,
|
||||
Self::BHP1024Commit => BHP1024Commit::NUM_ARGS,
|
||||
Self::BHP1024Hash => BHP1024Hash::NUM_ARGS,
|
||||
|
||||
Self::Pedersen64Commit => Pedersen64Commit::NUM_ARGS,
|
||||
Self::Pedersen64Hash => Pedersen64Hash::NUM_ARGS,
|
||||
Self::Pedersen128Commit => Pedersen128Commit::NUM_ARGS,
|
||||
Self::Pedersen128Hash => Pedersen128Hash::NUM_ARGS,
|
||||
|
||||
Self::Poseidon2Hash => Poseidon2Hash::NUM_ARGS,
|
||||
Self::Poseidon4Hash => Poseidon4Hash::NUM_ARGS,
|
||||
Self::Poseidon8Hash => Poseidon8Hash::NUM_ARGS,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether or not the first argument is an allowed type.
|
||||
pub fn first_arg_is_allowed_type(&self, type_: &Type) -> bool {
|
||||
match self {
|
||||
CoreInstruction::BHP256Commit => BHP256Commit::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP256Hash => BHP256Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP512Commit => BHP512Commit::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP512Hash => BHP512Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP768Commit => BHP768Commit::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP768Hash => BHP768Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP1024Commit => BHP1024Commit::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP1024Hash => BHP1024Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen64Commit => Pedersen64Commit::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen64Hash => Pedersen64Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen128Commit => Pedersen128Commit::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen128Hash => Pedersen128Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Poseidon2Hash => Poseidon2Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Poseidon4Hash => Poseidon4Hash::first_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Poseidon8Hash => Poseidon8Hash::first_arg_is_allowed_type(type_),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether or not the second argument is an allowed type.
|
||||
pub fn second_arg_is_allowed_type(&self, type_: &Type) -> bool {
|
||||
match self {
|
||||
CoreInstruction::BHP256Commit => BHP256Commit::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP256Hash => BHP256Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP512Commit => BHP512Commit::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP512Hash => BHP512Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP768Commit => BHP768Commit::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP768Hash => BHP768Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP1024Commit => BHP1024Commit::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::BHP1024Hash => BHP1024Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen64Commit => Pedersen64Commit::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen64Hash => Pedersen64Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen128Commit => Pedersen128Commit::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Pedersen128Hash => Pedersen128Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Poseidon2Hash => Poseidon2Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Poseidon4Hash => Poseidon4Hash::second_arg_is_allowed_type(type_),
|
||||
CoreInstruction::Poseidon8Hash => Poseidon8Hash::second_arg_is_allowed_type(type_),
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of the instruction output.
|
||||
pub fn return_type(&self) -> Type {
|
||||
match self {
|
||||
Self::BHP256Commit => BHP256Commit::return_type(),
|
||||
Self::BHP256Hash => BHP256Hash::return_type(),
|
||||
Self::BHP512Commit => BHP512Commit::return_type(),
|
||||
Self::BHP512Hash => BHP512Hash::return_type(),
|
||||
Self::BHP768Commit => BHP768Commit::return_type(),
|
||||
Self::BHP768Hash => BHP768Hash::return_type(),
|
||||
Self::BHP1024Commit => BHP1024Commit::return_type(),
|
||||
Self::BHP1024Hash => BHP1024Hash::return_type(),
|
||||
|
||||
Self::Pedersen64Commit => Pedersen64Commit::return_type(),
|
||||
Self::Pedersen64Hash => Pedersen64Hash::return_type(),
|
||||
Self::Pedersen128Commit => Pedersen128Commit::return_type(),
|
||||
Self::Pedersen128Hash => Pedersen128Hash::return_type(),
|
||||
|
||||
Self::Poseidon2Hash => Poseidon2Hash::return_type(),
|
||||
Self::Poseidon4Hash => Poseidon4Hash::return_type(),
|
||||
Self::Poseidon8Hash => Poseidon8Hash::return_type(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A core function of a core struct, e.g. `hash` or `commit`
|
||||
/// Provides required type information to the type checker.
|
||||
trait CoreFunction {
|
||||
const NUM_ARGS: usize;
|
||||
|
||||
/// Returns whether or not the first argument is an allowed type.
|
||||
fn first_arg_is_allowed_type(_: &Type) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns whether or not the second argument is an allowed type.
|
||||
fn second_arg_is_allowed_type(_: &Type) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The return type of the core function.
|
||||
fn return_type() -> Type;
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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::algorithms::CoreFunction;
|
||||
use leo_ast::{IntegerType, Type};
|
||||
|
||||
pub struct Pedersen64Hash;
|
||||
|
||||
impl CoreFunction for Pedersen64Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(
|
||||
type_,
|
||||
Type::Boolean
|
||||
| Type::Integer(IntegerType::I8)
|
||||
| Type::Integer(IntegerType::I16)
|
||||
| Type::Integer(IntegerType::I32)
|
||||
| Type::Integer(IntegerType::I64)
|
||||
| Type::Integer(IntegerType::U8)
|
||||
| Type::Integer(IntegerType::U16)
|
||||
| Type::Integer(IntegerType::U32)
|
||||
| Type::Integer(IntegerType::U64)
|
||||
| Type::String
|
||||
)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pedersen64Commit;
|
||||
|
||||
impl CoreFunction for Pedersen64Commit {
|
||||
const NUM_ARGS: usize = 2;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(
|
||||
type_,
|
||||
Type::Boolean
|
||||
| Type::Integer(IntegerType::I8)
|
||||
| Type::Integer(IntegerType::I16)
|
||||
| Type::Integer(IntegerType::I32)
|
||||
| Type::Integer(IntegerType::I64)
|
||||
| Type::Integer(IntegerType::U8)
|
||||
| Type::Integer(IntegerType::U16)
|
||||
| Type::Integer(IntegerType::U32)
|
||||
| Type::Integer(IntegerType::U64)
|
||||
| Type::String
|
||||
)
|
||||
}
|
||||
|
||||
fn second_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Scalar)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Group
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pedersen128Hash;
|
||||
|
||||
impl CoreFunction for Pedersen128Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Boolean | Type::Integer(_) | Type::String)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pedersen128Commit;
|
||||
|
||||
impl CoreFunction for Pedersen128Commit {
|
||||
const NUM_ARGS: usize = 2;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Boolean | Type::Integer(_) | Type::String)
|
||||
}
|
||||
|
||||
fn second_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
matches!(type_, Type::Scalar)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Group
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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::algorithms::CoreFunction;
|
||||
use leo_ast::Type;
|
||||
|
||||
pub struct Poseidon2Hash;
|
||||
|
||||
impl CoreFunction for Poseidon2Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Poseidon4Hash;
|
||||
|
||||
impl CoreFunction for Poseidon4Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Poseidon8Hash;
|
||||
|
||||
impl CoreFunction for Poseidon8Hash {
|
||||
const NUM_ARGS: usize = 1;
|
||||
|
||||
fn first_arg_is_allowed_type(type_: &Type) -> bool {
|
||||
!matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit)
|
||||
}
|
||||
|
||||
fn return_type() -> Type {
|
||||
Type::Field
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// Copyright (C) 2019-2023 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/>.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
mod algorithms;
|
||||
pub use algorithms::*;
|
@ -119,7 +119,7 @@ impl<'a> ParserContext<'a> {
|
||||
}
|
||||
|
||||
/// Emit the warning `warning`.
|
||||
pub(super) fn _emit_warning(&self, warning: ParserWarning) {
|
||||
pub(super) fn emit_warning(&self, warning: ParserWarning) {
|
||||
self.handler.emit_warning(warning.into());
|
||||
}
|
||||
|
||||
|
@ -297,6 +297,7 @@ impl ParserContext<'_> {
|
||||
Ok(inner)
|
||||
}
|
||||
|
||||
// TODO: Parse method call expressions directly and later put them into a canonical form.
|
||||
/// Returns an [`Expression`] AST node if the next tokens represent a
|
||||
/// method call expression.
|
||||
fn parse_method_call_expression(&mut self, receiver: Expression, method: Identifier) -> Result<Expression> {
|
||||
@ -316,9 +317,29 @@ impl ParserContext<'_> {
|
||||
right: Box::new(args.swap_remove(0)),
|
||||
}))
|
||||
} else {
|
||||
// Either an invalid unary/binary operator, or more arguments given.
|
||||
self.emit_err(ParserError::invalid_method_call(receiver, method, span));
|
||||
Ok(Expression::Err(ErrExpression { span }))
|
||||
// Attempt to parse the method call as a mapping operation.
|
||||
match (args.len(), CoreFunction::from_symbols(sym::Mapping, method.name)) {
|
||||
(1, Some(CoreFunction::MappingGet))
|
||||
| (2, Some(CoreFunction::MappingGetOrInit))
|
||||
| (2, Some(CoreFunction::MappingSet)) => {
|
||||
// Found an instance of `<mapping>.get`, `<mapping>.get_or`, or `<mapping>.set`
|
||||
Ok(Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: Type::Identifier(Identifier::new(sym::Mapping)),
|
||||
name: method,
|
||||
arguments: {
|
||||
let mut arguments = vec![receiver];
|
||||
arguments.extend(args);
|
||||
arguments
|
||||
},
|
||||
span,
|
||||
})))
|
||||
}
|
||||
_ => {
|
||||
// Either an invalid unary/binary operator, or more arguments given.
|
||||
self.emit_err(ParserError::invalid_method_call(receiver, method, args.len(), span));
|
||||
Ok(Expression::Err(ErrExpression { span }))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,7 +366,7 @@ impl ParserContext<'_> {
|
||||
span: module_name.span() + end,
|
||||
ty: type_,
|
||||
name: member_name,
|
||||
args,
|
||||
arguments: args,
|
||||
})
|
||||
} else {
|
||||
// Return the struct constant.
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
use leo_errors::{ParserError, Result};
|
||||
use leo_errors::{ParserError, ParserWarning, Result};
|
||||
use leo_span::sym;
|
||||
|
||||
const ASSIGN_TOKENS: &[Token] = &[
|
||||
@ -41,8 +41,6 @@ impl ParserContext<'_> {
|
||||
pub(crate) fn parse_statement(&mut self) -> Result<Statement> {
|
||||
match &self.token.token {
|
||||
Token::Return => Ok(Statement::Return(self.parse_return_statement()?)),
|
||||
Token::Increment => Ok(Statement::Increment(self.parse_increment_statement()?)),
|
||||
Token::Decrement => Ok(Statement::Decrement(self.parse_decrement_statement()?)),
|
||||
Token::If => Ok(Statement::Conditional(self.parse_conditional_statement()?)),
|
||||
Token::For => Ok(Statement::Iteration(Box::new(self.parse_loop_statement()?))),
|
||||
Token::Assert | Token::AssertEq | Token::AssertNeq => Ok(self.parse_assert_statement()?),
|
||||
@ -131,6 +129,27 @@ impl ParserContext<'_> {
|
||||
|
||||
Ok(Statement::Assign(Box::new(AssignStatement { span, place, value })))
|
||||
} else {
|
||||
// Check for `increment` and `decrement` statements. If found, emit a deprecation warning.
|
||||
if let Expression::Call(call_expression) = &place {
|
||||
match *call_expression.function {
|
||||
Expression::Identifier(Identifier { name: sym::decrement, .. }) => {
|
||||
self.emit_warning(ParserWarning::deprecated(
|
||||
"decrement",
|
||||
"Use `Mapping::{get, get_or_init, set}` for manipulating on-chain mappings.",
|
||||
place.span(),
|
||||
));
|
||||
}
|
||||
Expression::Identifier(Identifier { name: sym::increment, .. }) => {
|
||||
self.emit_warning(ParserWarning::deprecated(
|
||||
"increment",
|
||||
"Use `Mapping::{get, get_or_init, set}` for manipulating on-chain mappings.",
|
||||
place.span(),
|
||||
));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the expression as a statement.
|
||||
let end = self.expect(&Token::Semicolon)?;
|
||||
Ok(Statement::Expression(ExpressionStatement { span: place.span() + end, expression: place }))
|
||||
@ -174,38 +193,6 @@ impl ParserContext<'_> {
|
||||
Ok(ReturnStatement { span, expression, finalize_arguments: finalize_args })
|
||||
}
|
||||
|
||||
/// Returns a [`DecrementStatement`] AST node if the next tokens represent a decrement statement.
|
||||
fn parse_decrement_statement(&mut self) -> Result<DecrementStatement> {
|
||||
let start = self.expect(&Token::Decrement)?;
|
||||
self.expect(&Token::LeftParen)?;
|
||||
let mapping = self.expect_identifier()?;
|
||||
self.expect(&Token::Comma)?;
|
||||
let index = self.parse_expression()?;
|
||||
self.expect(&Token::Comma)?;
|
||||
let amount = self.parse_expression()?;
|
||||
self.eat(&Token::Comma);
|
||||
let end = self.expect(&Token::RightParen)?;
|
||||
self.expect(&Token::Semicolon)?;
|
||||
let span = start + end;
|
||||
Ok(DecrementStatement { mapping, index, amount, span })
|
||||
}
|
||||
|
||||
/// Returns an [`IncrementStatement`] AST node if the next tokens represent an increment statement.
|
||||
fn parse_increment_statement(&mut self) -> Result<IncrementStatement> {
|
||||
let start = self.expect(&Token::Increment)?;
|
||||
self.expect(&Token::LeftParen)?;
|
||||
let mapping = self.expect_identifier()?;
|
||||
self.expect(&Token::Comma)?;
|
||||
let index = self.parse_expression()?;
|
||||
self.expect(&Token::Comma)?;
|
||||
let amount = self.parse_expression()?;
|
||||
self.eat(&Token::Comma);
|
||||
let end = self.expect(&Token::RightParen)?;
|
||||
self.expect(&Token::Semicolon)?;
|
||||
let span = start + end;
|
||||
Ok(IncrementStatement { mapping, index, amount, span })
|
||||
}
|
||||
|
||||
/// Returns a [`ConditionalStatement`] AST node if the next tokens represent a conditional statement.
|
||||
fn parse_conditional_statement(&mut self) -> Result<ConditionalStatement> {
|
||||
let start = self.expect(&Token::If)?;
|
||||
|
@ -15,6 +15,7 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{tokenizer, ParserContext, SpannedToken};
|
||||
|
||||
use leo_ast::Statement;
|
||||
use leo_errors::{emitter::Handler, LeoError};
|
||||
use leo_span::{
|
||||
@ -30,6 +31,8 @@ use serde::Serialize;
|
||||
use serde_yaml::Value;
|
||||
use tokenizer::Token;
|
||||
|
||||
// TODO: Enable parser warnings for passing tests
|
||||
|
||||
struct TokenNamespace;
|
||||
|
||||
impl Namespace for TokenNamespace {
|
||||
@ -65,7 +68,9 @@ fn with_handler<T>(
|
||||
) -> Result<T, String> {
|
||||
let (handler, buf) = Handler::new_with_buf();
|
||||
let mut tokens = ParserContext::new(&handler, tokens);
|
||||
let parsed = handler.extend_if_error(logic(&mut tokens)).map_err(|_| buf.extract_errs().to_string())?;
|
||||
let parsed = handler
|
||||
.extend_if_error(logic(&mut tokens))
|
||||
.map_err(|_| buf.extract_errs().to_string() + &buf.extract_warnings().to_string())?;
|
||||
not_fully_consumed(&mut tokens)?;
|
||||
Ok(parsed)
|
||||
}
|
||||
|
@ -382,7 +382,6 @@ impl Token {
|
||||
"bool" => Token::Bool,
|
||||
"console" => Token::Console,
|
||||
"constant" => Token::Constant,
|
||||
"decrement" => Token::Decrement,
|
||||
"else" => Token::Else,
|
||||
"false" => Token::False,
|
||||
"field" => Token::Field,
|
||||
@ -398,7 +397,6 @@ impl Token {
|
||||
"if" => Token::If,
|
||||
"import" => Token::Import,
|
||||
"in" => Token::In,
|
||||
"increment" => Token::Increment,
|
||||
"inline" => Token::Inline,
|
||||
"let" => Token::Let,
|
||||
"leo" => Token::Leo,
|
||||
|
@ -113,7 +113,6 @@ pub enum Token {
|
||||
AssertNeq,
|
||||
Console,
|
||||
Constant,
|
||||
Decrement,
|
||||
Else,
|
||||
Finalize,
|
||||
For,
|
||||
@ -121,7 +120,6 @@ pub enum Token {
|
||||
If,
|
||||
Import,
|
||||
In,
|
||||
Increment,
|
||||
Inline,
|
||||
Let,
|
||||
Mapping,
|
||||
@ -153,7 +151,6 @@ pub const KEYWORD_TOKENS: &[Token] = &[
|
||||
Token::Bool,
|
||||
Token::Console,
|
||||
Token::Constant,
|
||||
Token::Decrement,
|
||||
Token::Else,
|
||||
Token::False,
|
||||
Token::Field,
|
||||
@ -169,7 +166,6 @@ pub const KEYWORD_TOKENS: &[Token] = &[
|
||||
Token::If,
|
||||
Token::Import,
|
||||
Token::In,
|
||||
Token::Increment,
|
||||
Token::Inline,
|
||||
Token::Let,
|
||||
Token::Mapping,
|
||||
@ -208,7 +204,6 @@ impl Token {
|
||||
Token::Bool => sym::bool,
|
||||
Token::Console => sym::console,
|
||||
Token::Constant => sym::constant,
|
||||
Token::Decrement => sym::decrement,
|
||||
Token::Else => sym::Else,
|
||||
Token::False => sym::False,
|
||||
Token::Field => sym::field,
|
||||
@ -224,7 +219,6 @@ impl Token {
|
||||
Token::If => sym::If,
|
||||
Token::Import => sym::import,
|
||||
Token::In => sym::In,
|
||||
Token::Increment => sym::increment,
|
||||
Token::Inline => sym::inline,
|
||||
Token::Let => sym::Let,
|
||||
Token::Leo => sym::leo,
|
||||
@ -340,7 +334,6 @@ impl fmt::Display for Token {
|
||||
AssertNeq => write!(f, "assert_neq"),
|
||||
Console => write!(f, "console"),
|
||||
Constant => write!(f, "constant"),
|
||||
Decrement => write!(f, "decrement"),
|
||||
Else => write!(f, "else"),
|
||||
Finalize => write!(f, "finalize"),
|
||||
For => write!(f, "for"),
|
||||
@ -348,7 +341,6 @@ impl fmt::Display for Token {
|
||||
If => write!(f, "if"),
|
||||
Import => write!(f, "import"),
|
||||
In => write!(f, "in"),
|
||||
Increment => write!(f, "increment"),
|
||||
Inline => write!(f, "inline"),
|
||||
Let => write!(f, "let"),
|
||||
Mapping => write!(f, "mapping"),
|
||||
|
@ -21,8 +21,10 @@ rust-version = "1.65"
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.9"
|
||||
[dependencies.snarkvm-console]
|
||||
workspace = true
|
||||
default-features = false
|
||||
features = [ "network" ]
|
||||
|
||||
[dependencies.leo-ast]
|
||||
path = "../ast"
|
||||
@ -40,9 +42,8 @@ version = "1.6.3"
|
||||
path = "../span"
|
||||
version = "1.6.3"
|
||||
|
||||
[dependencies.leo-core]
|
||||
path = "../core"
|
||||
version = "1.6.3"
|
||||
[dependencies.indexmap]
|
||||
version = "1.9"
|
||||
|
||||
[dependencies.itertools]
|
||||
version = "0.10.5"
|
||||
|
@ -38,6 +38,8 @@ pub struct CodeGenerator<'a> {
|
||||
/// The first element of the tuple indicate whether the composite is a record or not.
|
||||
/// The second element of the tuple is a string modifier used for code generation.
|
||||
pub(crate) composite_mapping: IndexMap<&'a Symbol, (bool, String)>,
|
||||
/// Mapping of global identifiers to their associated names.
|
||||
pub(crate) global_mapping: IndexMap<&'a Symbol, String>,
|
||||
/// Are we traversing a transition function?
|
||||
pub(crate) is_transition_function: bool,
|
||||
/// Are we traversing a finalize block?
|
||||
@ -56,6 +58,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
current_function: None,
|
||||
variable_mapping: IndexMap::new(),
|
||||
composite_mapping: IndexMap::new(),
|
||||
global_mapping: IndexMap::new(),
|
||||
is_transition_function: false,
|
||||
in_finalize: false,
|
||||
}
|
||||
|
@ -61,7 +61,10 @@ impl<'a> CodeGenerator<'a> {
|
||||
}
|
||||
|
||||
fn visit_identifier(&mut self, input: &'a Identifier) -> (String, String) {
|
||||
(self.variable_mapping.get(&input.name).unwrap().clone(), String::new())
|
||||
(
|
||||
self.variable_mapping.get(&input.name).or_else(|| self.global_mapping.get(&input.name)).unwrap().clone(),
|
||||
String::new(),
|
||||
)
|
||||
}
|
||||
|
||||
fn visit_err(&mut self, _input: &'a ErrExpression) -> (String, String) {
|
||||
@ -232,45 +235,103 @@ impl<'a> CodeGenerator<'a> {
|
||||
|
||||
// Pedersen64::hash() -> hash.ped64
|
||||
fn visit_associated_function(&mut self, input: &'a AssociatedFunction) -> (String, String) {
|
||||
// Write identifier as opcode. `Pedersen64` -> `ped64`.
|
||||
let symbol: &str = if let Type::Identifier(identifier) = input.ty {
|
||||
match identifier.name {
|
||||
sym::BHP256 => "bhp256",
|
||||
sym::BHP512 => "bhp512",
|
||||
sym::BHP768 => "bhp768",
|
||||
sym::BHP1024 => "bhp1024",
|
||||
sym::Pedersen64 => "ped64",
|
||||
sym::Pedersen128 => "ped128",
|
||||
sym::Poseidon2 => "psd2",
|
||||
sym::Poseidon4 => "psd4",
|
||||
sym::Poseidon8 => "psd8",
|
||||
_ => unreachable!("All core function calls should be known at this time."),
|
||||
}
|
||||
} else {
|
||||
unreachable!("All core function should be known at this time.")
|
||||
};
|
||||
|
||||
// Construct associated function call.
|
||||
let mut associated_function_call = format!(" {}.{symbol} ", input.name);
|
||||
let mut instructions = String::new();
|
||||
|
||||
// Visit each function argument and accumulate instructions from expressions.
|
||||
for arg in input.args.iter() {
|
||||
let (arg_string, arg_instructions) = self.visit_expression(arg);
|
||||
write!(associated_function_call, "{arg_string} ").expect("failed to write associated function argument");
|
||||
instructions.push_str(&arg_instructions);
|
||||
}
|
||||
let arguments = input
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|argument| {
|
||||
let (arg_string, arg_instructions) = self.visit_expression(argument);
|
||||
instructions.push_str(&arg_instructions);
|
||||
arg_string
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Push destination register to associated function call instruction.
|
||||
let destination_register = format!("r{}", self.next_register);
|
||||
writeln!(associated_function_call, "into {destination_register};")
|
||||
.expect("failed to write dest register for associated function");
|
||||
instructions.push_str(&associated_function_call);
|
||||
// Helper function to get a destination register for a function call.
|
||||
let mut get_destination_register = || {
|
||||
let destination_register = format!("r{}", self.next_register);
|
||||
self.next_register += 1;
|
||||
destination_register
|
||||
};
|
||||
|
||||
// Increment the register counter.
|
||||
self.next_register += 1;
|
||||
// Helper function to construct the instruction associated with a simple function call.
|
||||
// This assumes that the function call has one output.
|
||||
let mut construct_simple_function_call = |opcode: &Identifier, variant: &str, arguments: Vec<String>| {
|
||||
let mut instruction = format!(" {opcode}.{variant}");
|
||||
for argument in arguments {
|
||||
write!(instruction, " {argument}").expect("failed to write to string");
|
||||
}
|
||||
let destination_register = get_destination_register();
|
||||
write!(instruction, " into {destination_register};").expect("failed to write to string");
|
||||
(destination_register, instruction)
|
||||
};
|
||||
|
||||
(destination_register, instructions)
|
||||
// Construct the instruction.
|
||||
let (destination, instruction) = match input.ty {
|
||||
Type::Identifier(Identifier { name: sym::BHP256, .. }) => {
|
||||
construct_simple_function_call(&input.name, "bhp256", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::BHP512, .. }) => {
|
||||
construct_simple_function_call(&input.name, "bhp512", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::BHP768, .. }) => {
|
||||
construct_simple_function_call(&input.name, "bhp768", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::BHP1024, .. }) => {
|
||||
construct_simple_function_call(&input.name, "bhp1024", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::Pedersen64, .. }) => {
|
||||
construct_simple_function_call(&input.name, "ped64", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::Pedersen128, .. }) => {
|
||||
construct_simple_function_call(&input.name, "ped128", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::Poseidon2, .. }) => {
|
||||
construct_simple_function_call(&input.name, "psd2", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::Poseidon4, .. }) => {
|
||||
construct_simple_function_call(&input.name, "psd4", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::Poseidon8, .. }) => {
|
||||
construct_simple_function_call(&input.name, "psd8", arguments)
|
||||
}
|
||||
Type::Identifier(Identifier { name: sym::Mapping, .. }) => match input.name.name {
|
||||
sym::get => {
|
||||
let mut instruction = " get".to_string();
|
||||
let destination_register = get_destination_register();
|
||||
// Write the mapping name and the key.
|
||||
writeln!(instruction, " {}[{}] into {destination_register};", arguments[0], arguments[1])
|
||||
.expect("failed to write to string");
|
||||
(destination_register, instruction)
|
||||
}
|
||||
sym::get_or_init => {
|
||||
let mut instruction = " get.or_init".to_string();
|
||||
let destination_register = get_destination_register();
|
||||
// Write the mapping name, the key, and the default value.
|
||||
writeln!(
|
||||
instruction,
|
||||
" {}[{}] {} into {destination_register};",
|
||||
arguments[0], arguments[1], arguments[2]
|
||||
)
|
||||
.expect("failed to write to string");
|
||||
(destination_register, instruction)
|
||||
}
|
||||
sym::set => {
|
||||
let mut instruction = " set".to_string();
|
||||
// Write the value, mapping name, and the key.
|
||||
writeln!(instruction, " {} into {}[{}];", arguments[2], arguments[0], arguments[1])
|
||||
.expect("failed to write to string");
|
||||
(String::new(), instruction)
|
||||
}
|
||||
_ => unreachable!("The only variants of Mapping are get, get_or, and set"),
|
||||
},
|
||||
_ => unreachable!("All core functions should be known at this phase of compilation"),
|
||||
};
|
||||
// Add the instruction to the list of instructions.
|
||||
instructions.push_str(&instruction);
|
||||
|
||||
(destination, instructions)
|
||||
}
|
||||
|
||||
fn visit_access(&mut self, input: &'a AccessExpression) -> (String, String) {
|
||||
|
@ -166,8 +166,8 @@ impl<'a> CodeGenerator<'a> {
|
||||
// if it is a standard function generate an Aleo `closure`,
|
||||
// otherwise, it is an inline function, in which case a function should not be generated.
|
||||
let mut function_string = match function.variant {
|
||||
Variant::Transition => format!("function {}:\n", function.identifier),
|
||||
Variant::Standard => format!("closure {}:\n", function.identifier),
|
||||
Variant::Transition => format!("\nfunction {}:\n", function.identifier),
|
||||
Variant::Standard => format!("\nclosure {}:\n", function.identifier),
|
||||
Variant::Inline => return String::from("\n"),
|
||||
};
|
||||
|
||||
@ -249,7 +249,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
|
||||
fn visit_mapping(&mut self, mapping: &'a Mapping) -> String {
|
||||
// Create the prefix of the mapping string, e.g. `mapping foo:`.
|
||||
let mut mapping_string = format!("mapping {}:\n", mapping.identifier);
|
||||
let mut mapping_string = format!("\nmapping {}:\n", mapping.identifier);
|
||||
|
||||
// Helper to construct the string associated with the type.
|
||||
let create_type = |type_: &Type| {
|
||||
@ -276,6 +276,9 @@ impl<'a> CodeGenerator<'a> {
|
||||
// Create the value string, e.g. ` value as address.public`.
|
||||
mapping_string.push_str(&format!("\tvalue right as {};\n", create_type(&mapping.value_type)));
|
||||
|
||||
// Add the mapping to the variable mapping.
|
||||
self.global_mapping.insert(&mapping.identifier.name, mapping.identifier.to_string());
|
||||
|
||||
mapping_string
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,9 @@ use leo_ast::{
|
||||
Block,
|
||||
ConditionalStatement,
|
||||
ConsoleStatement,
|
||||
DecrementStatement,
|
||||
DefinitionStatement,
|
||||
Expression,
|
||||
ExpressionStatement,
|
||||
IncrementStatement,
|
||||
IterationStatement,
|
||||
Mode,
|
||||
Output,
|
||||
@ -46,10 +44,8 @@ impl<'a> CodeGenerator<'a> {
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
}
|
||||
@ -170,24 +166,6 @@ impl<'a> CodeGenerator<'a> {
|
||||
self.visit_expression(&input.expression).1
|
||||
}
|
||||
|
||||
fn visit_increment(&mut self, input: &'a IncrementStatement) -> String {
|
||||
let (index, mut instructions) = self.visit_expression(&input.index);
|
||||
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
||||
instructions.push_str(&amount_instructions);
|
||||
instructions.push_str(&format!(" increment {}[{index}] by {amount};\n", input.mapping));
|
||||
|
||||
instructions
|
||||
}
|
||||
|
||||
fn visit_decrement(&mut self, input: &'a DecrementStatement) -> String {
|
||||
let (index, mut instructions) = self.visit_expression(&input.index);
|
||||
let (amount, amount_instructions) = self.visit_expression(&input.amount);
|
||||
instructions.push_str(&amount_instructions);
|
||||
instructions.push_str(&format!(" decrement {}[{index}] by {amount};\n", input.mapping));
|
||||
|
||||
instructions
|
||||
}
|
||||
|
||||
fn visit_assign(&mut self, input: &'a AssignStatement) -> String {
|
||||
match (&input.place, &input.value) {
|
||||
(Expression::Identifier(identifier), _) => {
|
||||
|
@ -16,11 +16,68 @@
|
||||
|
||||
use crate::DeadCodeEliminator;
|
||||
|
||||
use leo_ast::{Expression, ExpressionReconstructor, Identifier, StructExpression, StructVariableInitializer};
|
||||
use leo_ast::{
|
||||
AccessExpression,
|
||||
AssociatedFunction,
|
||||
Expression,
|
||||
ExpressionReconstructor,
|
||||
Identifier,
|
||||
MemberAccess,
|
||||
StructExpression,
|
||||
StructVariableInitializer,
|
||||
TupleAccess,
|
||||
Type,
|
||||
};
|
||||
use leo_span::sym;
|
||||
|
||||
impl ExpressionReconstructor for DeadCodeEliminator {
|
||||
type AdditionalOutput = ();
|
||||
|
||||
/// Reconstructs the components of an access expression.
|
||||
fn reconstruct_access(&mut self, input: AccessExpression) -> (Expression, Self::AdditionalOutput) {
|
||||
(
|
||||
Expression::Access(match input {
|
||||
AccessExpression::AssociatedFunction(function) => {
|
||||
// If the associated function manipulates a mapping, mark the statement as necessary.
|
||||
match (&function.ty, function.name.name) {
|
||||
(Type::Identifier(Identifier { name: sym::Mapping, .. }), sym::get)
|
||||
| (Type::Identifier(Identifier { name: sym::Mapping, .. }), sym::get_or_init)
|
||||
| (Type::Identifier(Identifier { name: sym::Mapping, .. }), sym::set) => {
|
||||
self.is_necessary = true;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
// Reconstruct the access expression.
|
||||
let result = AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: function.ty,
|
||||
name: function.name,
|
||||
arguments: function
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|arg| self.reconstruct_expression(arg).0)
|
||||
.collect(),
|
||||
span: function.span,
|
||||
});
|
||||
// Unset `self.is_necessary`.
|
||||
self.is_necessary = false;
|
||||
result
|
||||
}
|
||||
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,
|
||||
}),
|
||||
AccessExpression::AssociatedConstant(constant) => AccessExpression::AssociatedConstant(constant),
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Reconstruct the components of the struct init expression.
|
||||
/// This is necessary since the reconstructor does not explicitly visit each component of the expression.
|
||||
fn reconstruct_struct_init(&mut self, input: StructExpression) -> (Expression, Self::AdditionalOutput) {
|
||||
|
@ -17,18 +17,17 @@
|
||||
use crate::DeadCodeEliminator;
|
||||
|
||||
use leo_ast::{
|
||||
AccessExpression,
|
||||
AssertStatement,
|
||||
AssertVariant,
|
||||
AssignStatement,
|
||||
Block,
|
||||
ConditionalStatement,
|
||||
ConsoleStatement,
|
||||
DecrementStatement,
|
||||
DefinitionStatement,
|
||||
Expression,
|
||||
ExpressionReconstructor,
|
||||
ExpressionStatement,
|
||||
IncrementStatement,
|
||||
IterationStatement,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
@ -125,24 +124,6 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
unreachable!("`ConsoleStatement`s should not be in the AST at this phase of compilation.")
|
||||
}
|
||||
|
||||
fn reconstruct_decrement(&mut self, input: DecrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// Set the `is_necessary` flag.
|
||||
self.is_necessary = true;
|
||||
|
||||
// Visit the statement.
|
||||
let statement = Statement::Decrement(DecrementStatement {
|
||||
mapping: input.mapping,
|
||||
index: self.reconstruct_expression(input.index).0,
|
||||
amount: self.reconstruct_expression(input.amount).0,
|
||||
span: input.span,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
self.is_necessary = false;
|
||||
|
||||
(statement, Default::default())
|
||||
}
|
||||
|
||||
/// Static single assignment replaces definition statements with assignment statements.
|
||||
fn reconstruct_definition(&mut self, _: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
unreachable!("`DefinitionStatement`s should not exist in the AST at this phase of compilation.")
|
||||
@ -168,30 +149,24 @@ impl StatementReconstructor for DeadCodeEliminator {
|
||||
|
||||
(statement, Default::default())
|
||||
}
|
||||
Expression::Access(AccessExpression::AssociatedFunction(associated_function)) => {
|
||||
// Visit the expression.
|
||||
(
|
||||
Statement::Expression(ExpressionStatement {
|
||||
expression: self
|
||||
.reconstruct_access(AccessExpression::AssociatedFunction(associated_function))
|
||||
.0,
|
||||
span: input.span,
|
||||
}),
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
// Any other expression is dead code, since they do not have side effects.
|
||||
// Note: array access expressions will have side effects and need to be handled here.
|
||||
_ => (Statement::dummy(Default::default()), Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
fn reconstruct_increment(&mut self, input: IncrementStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
// Set the `is_necessary` flag.
|
||||
self.is_necessary = true;
|
||||
|
||||
// Visit the statement.
|
||||
let statement = Statement::Increment(IncrementStatement {
|
||||
mapping: input.mapping,
|
||||
index: self.reconstruct_expression(input.index).0,
|
||||
amount: self.reconstruct_expression(input.amount).0,
|
||||
span: input.span,
|
||||
});
|
||||
|
||||
// Unset the `is_necessary` flag.
|
||||
self.is_necessary = false;
|
||||
|
||||
(statement, Default::default())
|
||||
}
|
||||
|
||||
/// Loop unrolling unrolls and removes iteration statements from the program.
|
||||
fn reconstruct_iteration(&mut self, _: IterationStatement) -> (Statement, Self::AdditionalOutput) {
|
||||
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
||||
|
@ -45,7 +45,11 @@ impl ExpressionReconstructor for Flattener<'_> {
|
||||
Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: function.ty,
|
||||
name: function.name,
|
||||
args: function.args.into_iter().map(|arg| self.reconstruct_expression(arg).0).collect(),
|
||||
arguments: function
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|arg| self.reconstruct_expression(arg).0)
|
||||
.collect(),
|
||||
span: function.span,
|
||||
}))
|
||||
}
|
||||
|
@ -53,8 +53,8 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
|
||||
AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: function.ty,
|
||||
name: function.name,
|
||||
args: function
|
||||
.args
|
||||
arguments: function
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|arg| {
|
||||
let (arg, mut stmts) = self.consume_expression(arg);
|
||||
|
@ -17,20 +17,20 @@
|
||||
use crate::{RenameTable, StaticSingleAssigner};
|
||||
|
||||
use leo_ast::{
|
||||
AccessExpression,
|
||||
AssertStatement,
|
||||
AssertVariant,
|
||||
AssignStatement,
|
||||
AssociatedFunction,
|
||||
Block,
|
||||
CallExpression,
|
||||
ConditionalStatement,
|
||||
ConsoleStatement,
|
||||
DecrementStatement,
|
||||
DefinitionStatement,
|
||||
Expression,
|
||||
ExpressionConsumer,
|
||||
ExpressionStatement,
|
||||
Identifier,
|
||||
IncrementStatement,
|
||||
IterationStatement,
|
||||
ReturnStatement,
|
||||
Statement,
|
||||
@ -200,25 +200,6 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
unreachable!("Parsing guarantees that console statements are not present in the program.")
|
||||
}
|
||||
|
||||
/// Consumes the expressions associated with the `DecrementStatement`, returning the simplified `DecrementStatement`.
|
||||
fn consume_decrement(&mut self, input: DecrementStatement) -> Self::Output {
|
||||
// First consume the expression associated with the amount.
|
||||
let (amount, mut statements) = self.consume_expression(input.amount);
|
||||
|
||||
// Then, consume the expression associated with the index.
|
||||
let (index, index_statements) = self.consume_expression(input.index);
|
||||
statements.extend(index_statements);
|
||||
|
||||
statements.push(Statement::Decrement(DecrementStatement {
|
||||
mapping: input.mapping,
|
||||
index,
|
||||
amount,
|
||||
span: input.span,
|
||||
}));
|
||||
|
||||
statements
|
||||
}
|
||||
|
||||
/// Consumes the `DefinitionStatement` into an `AssignStatement`, renaming the left-hand-side as appropriate.
|
||||
fn consume_definition(&mut self, definition: DefinitionStatement) -> Self::Output {
|
||||
// First consume the right-hand-side of the definition.
|
||||
@ -267,53 +248,52 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
|
||||
fn consume_expression_statement(&mut self, input: ExpressionStatement) -> Self::Output {
|
||||
let mut statements = Vec::new();
|
||||
|
||||
// Extract the call expression.
|
||||
let call = match input.expression {
|
||||
Expression::Call(call) => call,
|
||||
_ => unreachable!("Type checking guarantees that expression statements are always function calls."),
|
||||
// Helper to process the arguments of a function call, accumulating any statements produced.
|
||||
let mut process_arguments = |arguments: Vec<Expression>| {
|
||||
arguments
|
||||
.into_iter()
|
||||
.map(|argument| {
|
||||
let (argument, mut stmts) = self.consume_expression(argument);
|
||||
statements.append(&mut stmts);
|
||||
argument
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
// Process the arguments, accumulating any statements produced.
|
||||
let arguments = call
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|argument| {
|
||||
let (argument, mut stmts) = self.consume_expression(argument);
|
||||
statements.append(&mut stmts);
|
||||
argument
|
||||
})
|
||||
.collect();
|
||||
match input.expression {
|
||||
Expression::Call(call) => {
|
||||
// Process the arguments.
|
||||
let arguments = process_arguments(call.arguments);
|
||||
// Create and accumulate the new expression statement.
|
||||
// Note that we do not create a new assignment for the call expression; this is necessary for correct code generation.
|
||||
statements.push(Statement::Expression(ExpressionStatement {
|
||||
expression: Expression::Call(CallExpression {
|
||||
function: call.function,
|
||||
arguments,
|
||||
external: call.external,
|
||||
span: call.span,
|
||||
}),
|
||||
span: input.span,
|
||||
}));
|
||||
}
|
||||
Expression::Access(AccessExpression::AssociatedFunction(associated_function)) => {
|
||||
// Process the arguments.
|
||||
let arguments = process_arguments(associated_function.arguments);
|
||||
// Create and accumulate the new expression statement.
|
||||
// Note that we do not create a new assignment for the associated function; this is necessary for correct code generation.
|
||||
statements.push(Statement::Expression(ExpressionStatement {
|
||||
expression: Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction {
|
||||
ty: associated_function.ty,
|
||||
name: associated_function.name,
|
||||
arguments,
|
||||
span: associated_function.span,
|
||||
})),
|
||||
span: input.span,
|
||||
}))
|
||||
}
|
||||
|
||||
// Create and accumulate the new expression statement.
|
||||
// Note that we do not create a new assignment for the call expression; this is necessary for correct code generation.
|
||||
statements.push(Statement::Expression(ExpressionStatement {
|
||||
expression: Expression::Call(CallExpression {
|
||||
function: call.function,
|
||||
arguments,
|
||||
external: call.external,
|
||||
span: call.span,
|
||||
}),
|
||||
span: input.span,
|
||||
}));
|
||||
|
||||
statements
|
||||
}
|
||||
|
||||
/// Consumes the expressions associated with the `IncrementStatement`, returning a simplified `IncrementStatement`.
|
||||
fn consume_increment(&mut self, input: IncrementStatement) -> Self::Output {
|
||||
// First consume the expression associated with the amount.
|
||||
let (amount, mut statements) = self.consume_expression(input.amount);
|
||||
|
||||
// Then, consume the expression associated with the index.
|
||||
let (index, index_statements) = self.consume_expression(input.index);
|
||||
statements.extend(index_statements);
|
||||
|
||||
statements.push(Statement::Increment(IncrementStatement {
|
||||
mapping: input.mapping,
|
||||
index,
|
||||
amount,
|
||||
span: input.span,
|
||||
}));
|
||||
_ => unreachable!("Type checking guarantees that expression statements are always function calls."),
|
||||
}
|
||||
|
||||
statements
|
||||
}
|
||||
|
@ -44,45 +44,22 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
match input {
|
||||
AccessExpression::AssociatedFunction(access) => {
|
||||
// Check core struct name and function.
|
||||
if let Some(core_instruction) = self.check_core_function_call(&access.ty, &access.name) {
|
||||
// Check num input arguments.
|
||||
if core_instruction.num_args() != access.args.len() {
|
||||
// TODO: Better error messages.
|
||||
self.emit_err(TypeCheckerError::incorrect_num_args_to_call(
|
||||
core_instruction.num_args(),
|
||||
access.args.len(),
|
||||
input.span(),
|
||||
));
|
||||
}
|
||||
if let Some(core_instruction) = self.get_core_function_call(&access.ty, &access.name) {
|
||||
// Get the types of the arguments.
|
||||
let argument_types = access
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| (self.visit_expression(arg, &None), arg.span()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Check first argument type.
|
||||
if let Some(first_arg) = access.args.get(0usize) {
|
||||
if let Some(first_arg_type) = self.visit_expression(first_arg, &None) {
|
||||
if !core_instruction.first_arg_is_allowed_type(&first_arg_type) {
|
||||
// TODO: Better error messages.
|
||||
self.emit_err(TypeCheckerError::invalid_type(
|
||||
&first_arg_type,
|
||||
access.args.get(0).unwrap().span(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check that the types of the arguments are valid.
|
||||
let return_type = self.check_core_function_call(core_instruction, &argument_types, input.span());
|
||||
|
||||
// Check second argument type.
|
||||
if let Some(second_arg) = access.args.get(1usize) {
|
||||
if let Some(second_arg_type) = self.visit_expression(second_arg, &None) {
|
||||
if !core_instruction.second_arg_is_allowed_type(&second_arg_type) {
|
||||
// TODO: Better error messages.
|
||||
self.emit_err(TypeCheckerError::invalid_type(
|
||||
&second_arg_type,
|
||||
access.args.get(1).unwrap().span(),
|
||||
));
|
||||
}
|
||||
}
|
||||
// Check return type if the expected type is known.
|
||||
if let Some(expected) = expected {
|
||||
self.assert_type(&return_type, expected, input.span());
|
||||
}
|
||||
|
||||
// Check return type.
|
||||
return Some(self.assert_and_return_type(core_instruction.return_type(), expected, access.span()));
|
||||
return return_type;
|
||||
} else {
|
||||
self.emit_err(TypeCheckerError::invalid_core_function_call(access, access.span()));
|
||||
}
|
||||
|
@ -18,9 +18,10 @@ use crate::{DiGraphError, TypeChecker, VariableSymbol, VariableType};
|
||||
|
||||
use leo_ast::*;
|
||||
use leo_errors::TypeCheckerError;
|
||||
|
||||
use leo_span::sym;
|
||||
|
||||
use snarkvm_console::network::{Network, Testnet3};
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
// TODO: Cleanup logic for tuples.
|
||||
@ -77,11 +78,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
self.emit_err(TypeCheckerError::cyclic_function_dependency(path));
|
||||
}
|
||||
|
||||
// TODO: Use the snarkVM configurations to parameterize the check, need similar checks for structs (all in separate PR)
|
||||
// TODO: Need similar checks for structs (all in separate PR)
|
||||
// Check that the number of transitions does not exceed the maximum.
|
||||
if transition_count > 15 {
|
||||
if transition_count > Testnet3::MAX_FUNCTIONS {
|
||||
self.emit_err(TypeCheckerError::too_many_transitions(
|
||||
15,
|
||||
Testnet3::MAX_FUNCTIONS,
|
||||
input.program_id.name.span + input.program_id.network.span,
|
||||
));
|
||||
}
|
||||
@ -118,7 +119,6 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
}
|
||||
};
|
||||
check_has_field(sym::owner, Type::Address);
|
||||
check_has_field(sym::gates, Type::Integer(IntegerType::U64));
|
||||
}
|
||||
|
||||
for Member { mode, identifier, type_, span } in input.members.iter() {
|
||||
@ -146,9 +146,16 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
fn visit_mapping(&mut self, input: &'a Mapping) {
|
||||
// Check that a mapping's key type is valid.
|
||||
self.assert_type_is_defined(&input.key_type, input.span);
|
||||
// Check that a mapping's key type is not tuple types or mapping types.
|
||||
// Check that a mapping's key type is not a tuple, record, or mapping.
|
||||
match input.key_type {
|
||||
Type::Tuple(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("key", "tuple", input.span)),
|
||||
Type::Identifier(identifier) => {
|
||||
if let Some(struct_) = self.symbol_table.borrow().lookup_struct(identifier.name) {
|
||||
if struct_.is_record {
|
||||
self.emit_err(TypeCheckerError::invalid_mapping_type("key", "record", input.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note that this is not possible since the parser does not currently accept mapping types.
|
||||
Type::Mapping(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("key", "mapping", input.span)),
|
||||
_ => {}
|
||||
@ -156,9 +163,16 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
|
||||
// Check that a mapping's value type is valid.
|
||||
self.assert_type_is_defined(&input.value_type, input.span);
|
||||
// Check that a mapping's value type is not tuple types or mapping types.
|
||||
// Check that a mapping's value type is not a tuple, record or mapping.
|
||||
match input.value_type {
|
||||
Type::Tuple(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("value", "tuple", input.span)),
|
||||
Type::Identifier(identifier) => {
|
||||
if let Some(struct_) = self.symbol_table.borrow().lookup_struct(identifier.name) {
|
||||
if struct_.is_record {
|
||||
self.emit_err(TypeCheckerError::invalid_mapping_type("value", "record", input.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note that this is not possible since the parser does not currently accept mapping types.
|
||||
Type::Mapping(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("value", "mapping", input.span)),
|
||||
_ => {}
|
||||
@ -308,40 +322,64 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
|
||||
finalize.input.iter().for_each(|input_var| {
|
||||
// Check that the type of input parameter is defined.
|
||||
self.assert_type_is_defined(&input_var.type_(), input_var.span());
|
||||
// Check that the type of input parameter is not a tuple.
|
||||
if matches!(input_var.type_(), Type::Tuple(_)) {
|
||||
self.emit_err(TypeCheckerError::finalize_cannot_take_tuple_as_input(input_var.span()))
|
||||
}
|
||||
// Check that the input parameter is not constant or private.
|
||||
if input_var.mode() == Mode::Constant || input_var.mode() == Mode::Private {
|
||||
self.emit_err(TypeCheckerError::finalize_input_mode_must_be_public(input_var.span()));
|
||||
}
|
||||
// Check for conflicting variable names.
|
||||
if let Err(err) =
|
||||
self.symbol_table.borrow_mut().insert_variable(input_var.identifier().name, VariableSymbol {
|
||||
type_: input_var.type_(),
|
||||
span: input_var.identifier().span(),
|
||||
declaration: VariableType::Input(input_var.mode()),
|
||||
})
|
||||
{
|
||||
self.handler.emit_err(err);
|
||||
if self.assert_type_is_defined(&input_var.type_(), input_var.span()) {
|
||||
// Check that the input parameter is not a tuple.
|
||||
if matches!(input_var.type_(), Type::Tuple(_)) {
|
||||
self.emit_err(TypeCheckerError::finalize_cannot_take_tuple_as_input(input_var.span()))
|
||||
}
|
||||
// Check that the input parameter is not a record.
|
||||
if let Type::Identifier(identifier) = input_var.type_() {
|
||||
// Note that this unwrap is safe, as the type is defined.
|
||||
if self.symbol_table.borrow().lookup_struct(identifier.name).unwrap().is_record {
|
||||
self.emit_err(TypeCheckerError::finalize_cannot_take_record_as_input(input_var.span()))
|
||||
}
|
||||
}
|
||||
// Check that the input parameter is not constant or private.
|
||||
if input_var.mode() == Mode::Constant || input_var.mode() == Mode::Private {
|
||||
self.emit_err(TypeCheckerError::finalize_input_mode_must_be_public(input_var.span()));
|
||||
}
|
||||
// Check for conflicting variable names.
|
||||
if let Err(err) =
|
||||
self.symbol_table.borrow_mut().insert_variable(input_var.identifier().name, VariableSymbol {
|
||||
type_: input_var.type_(),
|
||||
span: input_var.identifier().span(),
|
||||
declaration: VariableType::Input(input_var.mode()),
|
||||
})
|
||||
{
|
||||
self.handler.emit_err(err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Type check the function's return type.
|
||||
// Check that the finalize block's return type is a unit type.
|
||||
// Note: This is a temporary restriction to be compatible with the current version of snarkVM.
|
||||
// Note: This restriction may be lifted in the future.
|
||||
// Note: This check is still compatible with the other checks below.
|
||||
if finalize.output_type != Type::Unit {
|
||||
self.emit_err(TypeCheckerError::finalize_cannot_return_value(finalize.span));
|
||||
}
|
||||
|
||||
// Type check the finalize block's return type.
|
||||
// Note that checking that each of the component types are defined is sufficient to guarantee that the `output_type` is defined.
|
||||
finalize.output.iter().for_each(|output_type| {
|
||||
// Check that the type of output is defined.
|
||||
self.assert_type_is_defined(&output_type.type_(), output_type.span());
|
||||
// Check that the type of the output is not a tuple. This is necessary to forbid nested tuples.
|
||||
if matches!(&output_type.type_(), Type::Tuple(_)) {
|
||||
self.emit_err(TypeCheckerError::nested_tuple_type(output_type.span()))
|
||||
}
|
||||
// Check that the mode of the output is valid.
|
||||
// Note that a finalize block can have only public outputs.
|
||||
if matches!(output_type.mode(), Mode::Constant | Mode::Private) {
|
||||
self.emit_err(TypeCheckerError::finalize_output_mode_must_be_public(output_type.span()));
|
||||
if self.assert_type_is_defined(&output_type.type_(), output_type.span()) {
|
||||
// Check that the output is not a tuple. This is necessary to forbid nested tuples.
|
||||
if matches!(&output_type.type_(), Type::Tuple(_)) {
|
||||
self.emit_err(TypeCheckerError::nested_tuple_type(output_type.span()))
|
||||
}
|
||||
// Check that the output is not a record.
|
||||
if let Type::Identifier(identifier) = output_type.type_() {
|
||||
// Note that this unwrap is safe, as the type is defined.
|
||||
if self.symbol_table.borrow().lookup_struct(identifier.name).unwrap().is_record {
|
||||
self.emit_err(TypeCheckerError::finalize_cannot_output_record(output_type.span()))
|
||||
}
|
||||
}
|
||||
// Check that the mode of the output is valid.
|
||||
// Note that a finalize block can have only public outputs.
|
||||
if matches!(output_type.mode(), Mode::Constant | Mode::Private) {
|
||||
self.emit_err(TypeCheckerError::finalize_output_mode_must_be_public(output_type.span()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -35,10 +35,8 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
Statement::Block(stmt) => self.visit_block(stmt),
|
||||
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||
Statement::Console(stmt) => self.visit_console(stmt),
|
||||
Statement::Decrement(stmt) => self.visit_decrement(stmt),
|
||||
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||
Statement::Increment(stmt) => self.visit_increment(stmt),
|
||||
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||
Statement::Return(stmt) => self.visit_return(stmt),
|
||||
}
|
||||
@ -152,35 +150,6 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
unreachable!("Parsing guarantees that console statements are not present in the AST.");
|
||||
}
|
||||
|
||||
fn visit_decrement(&mut self, input: &'a DecrementStatement) {
|
||||
if !self.is_finalize {
|
||||
self.emit_err(TypeCheckerError::increment_or_decrement_outside_finalize(input.span()));
|
||||
}
|
||||
|
||||
// Assert that the first operand is a mapping.
|
||||
let mapping_type = self.visit_identifier(&input.mapping, &None);
|
||||
self.assert_mapping_type(&mapping_type, input.span());
|
||||
|
||||
match mapping_type {
|
||||
None => self.emit_err(TypeCheckerError::could_not_determine_type(input.mapping, input.mapping.span)),
|
||||
Some(Type::Mapping(mapping_type)) => {
|
||||
// Check that the index matches the key type of the mapping.
|
||||
let index_type = self.visit_expression(&input.index, &None);
|
||||
self.assert_type(&index_type, &mapping_type.key, input.index.span());
|
||||
|
||||
// Check that the amount matches the value type of the mapping.
|
||||
let amount_type = self.visit_expression(&input.amount, &None);
|
||||
self.assert_type(&amount_type, &mapping_type.value, input.amount.span());
|
||||
|
||||
// Check that the amount type is incrementable.
|
||||
self.assert_field_group_scalar_int_type(&amount_type, input.amount.span());
|
||||
}
|
||||
Some(mapping_type) => {
|
||||
self.emit_err(TypeCheckerError::expected_one_type_of("mapping", mapping_type, input.mapping.span))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_definition(&mut self, input: &'a DefinitionStatement) {
|
||||
let declaration =
|
||||
if input.declaration_type == DeclarationType::Const { VariableType::Const } else { VariableType::Mut };
|
||||
@ -251,44 +220,17 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
|
||||
fn visit_expression_statement(&mut self, input: &'a ExpressionStatement) {
|
||||
// Expression statements can only be function calls.
|
||||
if !matches!(input.expression, Expression::Call(_)) {
|
||||
if !matches!(
|
||||
input.expression,
|
||||
Expression::Call(_) | Expression::Access(AccessExpression::AssociatedFunction(_))
|
||||
) {
|
||||
self.emit_err(TypeCheckerError::expression_statement_must_be_function_call(input.span()));
|
||||
} else {
|
||||
// Check the expression.
|
||||
// TODO: Should the output type be restricted to unit types?
|
||||
self.visit_expression(&input.expression, &None);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_increment(&mut self, input: &'a IncrementStatement) {
|
||||
if !self.is_finalize {
|
||||
self.emit_err(TypeCheckerError::increment_or_decrement_outside_finalize(input.span()));
|
||||
}
|
||||
|
||||
// Assert that the first operand is a mapping.
|
||||
let mapping_type = self.visit_identifier(&input.mapping, &None);
|
||||
self.assert_mapping_type(&mapping_type, input.span());
|
||||
|
||||
match mapping_type {
|
||||
None => self.emit_err(TypeCheckerError::could_not_determine_type(input.mapping, input.mapping.span)),
|
||||
Some(Type::Mapping(mapping_type)) => {
|
||||
// Check that the index matches the key type of the mapping.
|
||||
let index_type = self.visit_expression(&input.index, &None);
|
||||
self.assert_type(&index_type, &mapping_type.key, input.index.span());
|
||||
|
||||
// Check that the amount matches the value type of the mapping.
|
||||
let amount_type = self.visit_expression(&input.amount, &None);
|
||||
self.assert_type(&amount_type, &mapping_type.value, input.amount.span());
|
||||
|
||||
// Check that the amount type is incrementable.
|
||||
self.assert_field_group_scalar_int_type(&amount_type, input.amount.span());
|
||||
}
|
||||
Some(mapping_type) => {
|
||||
self.emit_err(TypeCheckerError::expected_one_type_of("mapping", mapping_type, input.mapping.span))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_iteration(&mut self, input: &'a IterationStatement) {
|
||||
let iter_type = &Some(input.type_.clone());
|
||||
self.assert_int_type(iter_type, input.variable.span);
|
||||
|
@ -16,8 +16,7 @@
|
||||
|
||||
use crate::{CallGraph, StructGraph, SymbolTable};
|
||||
|
||||
use leo_ast::{Identifier, IntegerType, Node, Type, Variant};
|
||||
use leo_core::*;
|
||||
use leo_ast::{CoreFunction, Identifier, IntegerType, MappingType, Node, Type, Variant};
|
||||
use leo_errors::{emitter::Handler, TypeCheckerError};
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
@ -305,10 +304,10 @@ impl<'a> TypeChecker<'a> {
|
||||
|
||||
/// Emits an error if the `struct` is not a core library struct.
|
||||
/// Emits an error if the `function` is not supported by the struct.
|
||||
pub(crate) fn check_core_function_call(&self, struct_: &Type, function: &Identifier) -> Option<CoreInstruction> {
|
||||
pub(crate) fn get_core_function_call(&self, struct_: &Type, function: &Identifier) -> Option<CoreFunction> {
|
||||
if let Type::Identifier(ident) = struct_ {
|
||||
// Lookup core struct
|
||||
match CoreInstruction::from_symbols(ident.name, function.name) {
|
||||
match CoreFunction::from_symbols(ident.name, function.name) {
|
||||
None => {
|
||||
// Not a core library struct.
|
||||
self.emit_err(TypeCheckerError::invalid_core_function(ident.name, function.name, ident.span()));
|
||||
@ -319,6 +318,177 @@ impl<'a> TypeChecker<'a> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Type checks the inputs to a core function call and returns the expected output type.
|
||||
/// Emits an error if the correct number of arguments are not provided.
|
||||
/// Emits an error if the arguments are not of the correct type.
|
||||
pub(crate) fn check_core_function_call(
|
||||
&self,
|
||||
core_function: CoreFunction,
|
||||
arguments: &[(Option<Type>, Span)],
|
||||
function_span: Span,
|
||||
) -> Option<Type> {
|
||||
// Check that the number of arguments is correct.
|
||||
if arguments.len() != core_function.num_args() {
|
||||
self.emit_err(TypeCheckerError::incorrect_num_args_to_call(
|
||||
core_function.num_args(),
|
||||
arguments.len(),
|
||||
function_span,
|
||||
));
|
||||
return None;
|
||||
}
|
||||
|
||||
// Helper to check that the type of argument is not a mapping, tuple, err, or unit type.
|
||||
let check_not_mapping_tuple_err_unit = |type_: &Option<Type>, span: &Span| {
|
||||
self.check_type(
|
||||
|type_: &Type| !matches!(type_, Type::Mapping(_) | Type::Tuple(_) | Type::Err | Type::Unit),
|
||||
"address, boolean, field, group, struct, integer, scalar, scalar, string".to_string(),
|
||||
type_,
|
||||
*span,
|
||||
);
|
||||
};
|
||||
|
||||
// Helper to check that the type of the argument is a valid input to a Pedersen hash/commit with 64-bit inputs.
|
||||
let check_pedersen_64_bit_input = |type_: &Option<Type>, span: &Span| {
|
||||
self.check_type(
|
||||
|type_: &Type| {
|
||||
matches!(
|
||||
type_,
|
||||
Type::Boolean
|
||||
| Type::Integer(IntegerType::I8)
|
||||
| Type::Integer(IntegerType::I16)
|
||||
| Type::Integer(IntegerType::I32)
|
||||
| Type::Integer(IntegerType::I64)
|
||||
| Type::Integer(IntegerType::U8)
|
||||
| Type::Integer(IntegerType::U16)
|
||||
| Type::Integer(IntegerType::U32)
|
||||
| Type::Integer(IntegerType::U64)
|
||||
| Type::String
|
||||
)
|
||||
},
|
||||
"boolean, integer (up to 64 bits), string".to_string(),
|
||||
type_,
|
||||
*span,
|
||||
);
|
||||
};
|
||||
|
||||
// Helper to check that the type of the argument is a valid input to a Pedersen hash/commit with 128-bit inputs.
|
||||
let check_pedersen_128_bit_input = |type_: &Option<Type>, span: &Span| {
|
||||
self.check_type(
|
||||
|type_: &Type| matches!(type_, Type::Boolean | Type::Integer(_) | Type::String),
|
||||
"boolean, integer, string".to_string(),
|
||||
type_,
|
||||
*span,
|
||||
);
|
||||
};
|
||||
|
||||
// Check that the arguments are of the correct type.
|
||||
match core_function {
|
||||
CoreFunction::BHP256Commit
|
||||
| CoreFunction::BHP512Commit
|
||||
| CoreFunction::BHP768Commit
|
||||
| CoreFunction::BHP1024Commit => {
|
||||
// Check that the first argument is not a mapping, tuple, err, or unit type.
|
||||
check_not_mapping_tuple_err_unit(&arguments[0].0, &arguments[0].1);
|
||||
// Check that the second argument is a scalar.
|
||||
self.assert_scalar_type(&arguments[1].0, arguments[1].1);
|
||||
Some(Type::Field)
|
||||
}
|
||||
CoreFunction::BHP256Hash
|
||||
| CoreFunction::BHP512Hash
|
||||
| CoreFunction::BHP768Hash
|
||||
| CoreFunction::BHP1024Hash => {
|
||||
// Check that the first argument is not a mapping, tuple, err, or unit type.
|
||||
check_not_mapping_tuple_err_unit(&arguments[0].0, &arguments[0].1);
|
||||
Some(Type::Field)
|
||||
}
|
||||
CoreFunction::Pedersen64Commit => {
|
||||
// Check that the first argument is either a boolean, integer up to 64 bits, or field element.
|
||||
check_pedersen_64_bit_input(&arguments[0].0, &arguments[0].1);
|
||||
// Check that the second argument is a scalar.
|
||||
self.assert_scalar_type(&arguments[1].0, arguments[1].1);
|
||||
|
||||
Some(Type::Group)
|
||||
}
|
||||
CoreFunction::Pedersen64Hash => {
|
||||
// Check that the first argument is either a boolean, integer up to 64 bits, or field element.
|
||||
check_pedersen_64_bit_input(&arguments[0].0, &arguments[0].1);
|
||||
Some(Type::Field)
|
||||
}
|
||||
CoreFunction::Pedersen128Commit => {
|
||||
// Check that the first argument is either a boolean, integer, or field element.
|
||||
check_pedersen_128_bit_input(&arguments[0].0, &arguments[0].1);
|
||||
// Check that the second argument is a scalar.
|
||||
self.assert_scalar_type(&arguments[1].0, arguments[1].1);
|
||||
|
||||
Some(Type::Group)
|
||||
}
|
||||
CoreFunction::Pedersen128Hash => {
|
||||
// Check that the first argument is either a boolean, integer, or field element.
|
||||
check_pedersen_128_bit_input(&arguments[0].0, &arguments[0].1);
|
||||
Some(Type::Field)
|
||||
}
|
||||
CoreFunction::Poseidon2Hash | CoreFunction::Poseidon4Hash | CoreFunction::Poseidon8Hash => {
|
||||
// Check that the first argument is not a mapping, tuple, err, or unit type.
|
||||
check_not_mapping_tuple_err_unit(&arguments[0].0, &arguments[0].1);
|
||||
Some(Type::Field)
|
||||
}
|
||||
CoreFunction::MappingGet => {
|
||||
// Check that the operation is invoked in a `finalize` block.
|
||||
if !self.is_finalize {
|
||||
self.handler
|
||||
.emit_err(TypeCheckerError::invalid_operation_outside_finalize("Mapping::get", function_span))
|
||||
}
|
||||
// Check that the first argument is a mapping.
|
||||
if let Some(mapping_type) = self.assert_mapping_type(&arguments[0].0, arguments[0].1) {
|
||||
// Check that the second argument matches the key type of the mapping.
|
||||
self.assert_type(&arguments[1].0, &mapping_type.key, arguments[1].1);
|
||||
// Return the value type of the mapping.
|
||||
Some(*mapping_type.value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
CoreFunction::MappingGetOrInit => {
|
||||
// Check that the operation is invoked in a `finalize` block.
|
||||
if !self.is_finalize {
|
||||
self.handler.emit_err(TypeCheckerError::invalid_operation_outside_finalize(
|
||||
"Mapping::get_or",
|
||||
function_span,
|
||||
))
|
||||
}
|
||||
// Check that the first argument is a mapping.
|
||||
if let Some(mapping_type) = self.assert_mapping_type(&arguments[0].0, arguments[0].1) {
|
||||
// Check that the second argument matches the key type of the mapping.
|
||||
self.assert_type(&arguments[1].0, &mapping_type.key, arguments[1].1);
|
||||
// Check that the third argument matches the value type of the mapping.
|
||||
self.assert_type(&arguments[2].0, &mapping_type.value, arguments[2].1);
|
||||
// Return the value type of the mapping.
|
||||
Some(*mapping_type.value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
CoreFunction::MappingSet => {
|
||||
// Check that the operation is invoked in a `finalize` block.
|
||||
if !self.is_finalize {
|
||||
self.handler
|
||||
.emit_err(TypeCheckerError::invalid_operation_outside_finalize("Mapping::set", function_span))
|
||||
}
|
||||
// Check that the first argument is a mapping.
|
||||
if let Some(mapping_type) = self.assert_mapping_type(&arguments[0].0, arguments[0].1) {
|
||||
// Check that the second argument matches the key type of the mapping.
|
||||
self.assert_type(&arguments[1].0, &mapping_type.key, arguments[1].1);
|
||||
// Check that the third argument matches the value type of the mapping.
|
||||
self.assert_type(&arguments[2].0, &mapping_type.value, arguments[2].1);
|
||||
// Return the mapping type.
|
||||
Some(Type::Unit)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `struct` type and emits an error if the `expected` type does not match.
|
||||
pub(crate) fn check_expected_struct(&mut self, struct_: Identifier, expected: &Option<Type>, span: Span) -> Type {
|
||||
if let Some(expected) = expected {
|
||||
@ -381,8 +551,12 @@ impl<'a> TypeChecker<'a> {
|
||||
}
|
||||
|
||||
/// Emits an error if the type is not a mapping.
|
||||
pub(crate) fn assert_mapping_type(&self, type_: &Option<Type>, span: Span) {
|
||||
self.check_type(|type_| matches!(type_, Type::Mapping(_)), "mapping".to_string(), type_, span)
|
||||
pub(crate) fn assert_mapping_type(&self, type_: &Option<Type>, span: Span) -> Option<MappingType> {
|
||||
self.check_type(|type_| matches!(type_, Type::Mapping(_)), "mapping".to_string(), type_, span);
|
||||
match type_ {
|
||||
Some(Type::Mapping(mapping_type)) => Some(mapping_type.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,12 +147,16 @@ symbols! {
|
||||
BHP768,
|
||||
BHP1024,
|
||||
commit,
|
||||
get,
|
||||
get_or_init,
|
||||
hash,
|
||||
Mapping,
|
||||
Pedersen64,
|
||||
Pedersen128,
|
||||
Poseidon2,
|
||||
Poseidon4,
|
||||
Poseidon8,
|
||||
set,
|
||||
|
||||
// types
|
||||
address,
|
||||
|
@ -202,8 +202,8 @@ create_messages!(
|
||||
/// Parsed an unknown method call on the type of an expression.
|
||||
@formatted
|
||||
invalid_method_call {
|
||||
args: (expr: impl Display, func: impl Display),
|
||||
msg: format!("The type of `{expr}` has no associated function `{func}`"),
|
||||
args: (expr: impl Display, func: impl Display, num_args: impl Display),
|
||||
msg: format!("The type of `{expr}` has no associated function `{func}` that takes {num_args} argument(s)."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
use crate::create_messages;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
create_messages!(
|
||||
/// ParserWarning enum that represents all the warnings for the `leo-parser` crate.
|
||||
ParserWarning,
|
||||
@ -23,10 +25,21 @@ create_messages!(
|
||||
code_prefix: "PAR",
|
||||
|
||||
/// For when a user used const on a parameter or input instead of constant.
|
||||
@formatted
|
||||
const_parameter_or_input {
|
||||
args: (),
|
||||
msg: "`constant` is preferred over `const` for function parameters to indicate a R1CS constant.",
|
||||
help: None,
|
||||
}
|
||||
@formatted
|
||||
const_parameter_or_input {
|
||||
args: (),
|
||||
msg: "`constant` is preferred over `const` for function parameters to indicate a R1CS constant.",
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when a keyword is deprecated but could be used as a valid identifier.
|
||||
@formatted
|
||||
deprecated {
|
||||
args: (keyword: impl Display, help: impl Display),
|
||||
msg: format!("The keyword `{keyword}` is deprecated."),
|
||||
help: Some(help.to_string()),
|
||||
}
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
@ -118,7 +118,7 @@ create_messages!(
|
||||
invalid_core_function {
|
||||
args: (struct_: impl Display, function: impl Display),
|
||||
msg: format!(
|
||||
"The instruction {struct_}::{function} is not a valid core function.",
|
||||
"{struct_}::{function} is not a valid core function.",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
@ -327,9 +327,9 @@ create_messages!(
|
||||
}
|
||||
|
||||
@formatted
|
||||
increment_or_decrement_outside_finalize {
|
||||
args: (),
|
||||
msg: format!("`increment` or `decrement` statements must be inside a finalize block."),
|
||||
invalid_operation_outside_finalize {
|
||||
args: (operation: impl Display),
|
||||
msg: format!("`{operation}` must be inside a finalize block."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
@ -573,4 +573,25 @@ create_messages!(
|
||||
msg: format!("Cannot call an external `inline` function."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
@formatted
|
||||
finalize_cannot_take_record_as_input {
|
||||
args: (),
|
||||
msg: format!("A finalize block cannot take in a record as input."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
@formatted
|
||||
finalize_cannot_output_record {
|
||||
args: (),
|
||||
msg: format!("A finalize block cannot return a record."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
@formatted
|
||||
finalize_cannot_return_value {
|
||||
args: (),
|
||||
msg: format!("A finalize block cannot return a value."),
|
||||
help: None,
|
||||
}
|
||||
);
|
||||
|
@ -50,7 +50,8 @@ program basic_bank.aleo {
|
||||
// - `hash` : The hash of the token owner.
|
||||
// - `amount`: The amount of tokens that were deposited.
|
||||
finalize deposit(hash: field, amount: u64) {
|
||||
increment(balances, hash, amount);
|
||||
let current_amount: u64 = Mapping::get_or_init(balances, hash, 0u64);
|
||||
Mapping::set(balances, hash, current_amount + amount);
|
||||
}
|
||||
|
||||
// Returns a new Token containing the amount of money withdrawn.
|
||||
@ -78,7 +79,8 @@ program basic_bank.aleo {
|
||||
// - `hash` : The hash of the token owner.
|
||||
// - `amount`: The amount of tokens that were withdrawn.
|
||||
finalize withdraw(hash: field, amount: u64) {
|
||||
decrement(balances, hash, amount);
|
||||
let current_amount: u64 = Mapping::get_or_init(balances, hash, 0u64);
|
||||
Mapping::set(balances, hash, current_amount - amount);
|
||||
}
|
||||
|
||||
// Returns the total amount of tokens after compounding interest.
|
||||
|
@ -24,7 +24,8 @@ program token.aleo {
|
||||
// Increments `account[receiver]` by `amount`.
|
||||
// If `account[receiver]` does not exist, it will be created.
|
||||
// If `account[receiver] + amount` overflows, `mint_public` is reverted.
|
||||
increment(account, receiver, amount);
|
||||
let current_amount: u64 = Mapping::get_or_init(account, receiver, 0u64);
|
||||
Mapping::set(account, receiver, current_amount + amount);
|
||||
}
|
||||
|
||||
// The function `mint_private` initializes a new record with the specified amount of tokens for the receiver.
|
||||
@ -46,11 +47,13 @@ program token.aleo {
|
||||
// Decrements `account[sender]` by `amount`.
|
||||
// If `account[sender]` does not exist, it will be created.
|
||||
// If `account[sender] - amount` underflows, `transfer_public` is reverted.
|
||||
decrement(account, sender, amount);
|
||||
let sender_amount: u64 = Mapping::get_or_init(account, sender, 0u64);
|
||||
Mapping::set(account, sender, sender_amount - amount);
|
||||
// Increments `account[receiver]` by `amount`.
|
||||
// If `account[receiver]` does not exist, it will be created.
|
||||
// If `account[receiver] + amount` overflows, `transfer_public` is reverted.
|
||||
increment(account, receiver, amount);
|
||||
let receiver_amount: u64 = Mapping::get_or_init(account, receiver, 0u64);
|
||||
Mapping::set(account, receiver, receiver_amount + amount);
|
||||
}
|
||||
|
||||
// The function `transfer_private` sends the specified token amount to the token receiver from the specified token record.
|
||||
@ -102,7 +105,8 @@ program token.aleo {
|
||||
// Increments `account[receiver]` by `amount`.
|
||||
// If `account[receiver]` does not exist, it will be created.
|
||||
// If `account[receiver] + amount` overflows, `transfer_private_to_public` is reverted.
|
||||
increment(account, receiver, amount);
|
||||
let current_amount: u64 = Mapping::get_or_init(account, receiver, 0u64);
|
||||
Mapping::set(account, receiver, current_amount + amount);
|
||||
}
|
||||
|
||||
// The function `transfer_public_to_private` turns a specified token amount from `account` into a token record for the specified receiver.
|
||||
@ -124,7 +128,8 @@ program token.aleo {
|
||||
// Decrements `account[sender]` by `amount`.
|
||||
// If `account[sender]` does not exist, it will be created.
|
||||
// If `account[sender] - amount` underflows, `transfer_public_to_private` is reverted.
|
||||
decrement(account, sender, amount);
|
||||
let current_amount: u64 = Mapping::get_or_init(account, sender, 0u64);
|
||||
Mapping::set(account, sender, current_amount - amount);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ program vote.aleo {
|
||||
}
|
||||
// Create a new proposal in the "tickets" mapping.
|
||||
finalize propose(public id: field) {
|
||||
increment(tickets, id, 0u64);
|
||||
Mapping::set(tickets, id, 0u64);
|
||||
}
|
||||
|
||||
// Create a new ticket to vote with.
|
||||
@ -70,7 +70,8 @@ program vote.aleo {
|
||||
}
|
||||
// Create a new ticket on a proposal in the "tickets" mapping.
|
||||
finalize new_ticket(public pid: field) {
|
||||
increment(tickets, pid, 1u64);
|
||||
let current: u64 = Mapping::get_or_init(tickets, pid, 0u64);
|
||||
Mapping::set(tickets, pid, current + 1u64);
|
||||
}
|
||||
|
||||
// Vote privately to agree with a proposal.
|
||||
@ -80,7 +81,8 @@ program vote.aleo {
|
||||
}
|
||||
finalize agree(public pid: field) {
|
||||
// Publicly increment the number of agree votes.
|
||||
increment(agree_votes, pid, 1u64);
|
||||
let current: u64 = Mapping::get_or_init(agree_votes, pid, 0u64);
|
||||
Mapping::set(agree_votes, pid, current + 1u64);
|
||||
}
|
||||
|
||||
// Vote privately to disagree with a proposal.
|
||||
@ -90,6 +92,7 @@ program vote.aleo {
|
||||
}
|
||||
finalize disagree(pid: field) {
|
||||
// Publicly increment the number of disagree votes.
|
||||
increment(disagree_votes, pid, 1u64);
|
||||
let current: u64 = Mapping::get_or_init(disagree_votes, pid, 0u64);
|
||||
Mapping::set(disagree_votes, pid, current + 1u64);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use leo_package::{
|
||||
};
|
||||
use leo_span::{symbol::with_session_globals, Symbol};
|
||||
|
||||
use aleo::commands::Build as AleoBuild;
|
||||
use snarkvm::cli::Build as AleoBuild;
|
||||
|
||||
use clap::StructOpt;
|
||||
use indexmap::IndexMap;
|
||||
|
@ -21,8 +21,8 @@ pub use build::Build;
|
||||
pub mod clean;
|
||||
pub use clean::Clean;
|
||||
|
||||
pub mod deploy;
|
||||
pub use deploy::Deploy;
|
||||
// pub mod deploy;
|
||||
// pub use deploy::Deploy;
|
||||
|
||||
pub mod new;
|
||||
pub use new::New;
|
||||
|
@ -22,7 +22,7 @@ use leo_errors::{CliError, PackageError, Result};
|
||||
use leo_package::{build::BUILD_DIRECTORY_NAME, package::Package};
|
||||
use snarkvm::file::AleoFile;
|
||||
|
||||
use aleo::commands::New as AleoNew;
|
||||
use snarkvm::cli::New as AleoNew;
|
||||
|
||||
use clap::StructOpt;
|
||||
use tracing::span::Span;
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||
use leo_errors::{CliError, PackageError, Result};
|
||||
use leo_package::build::BuildDirectory;
|
||||
|
||||
use aleo::commands::Run as AleoRun;
|
||||
use snarkvm::cli::Run as AleoRun;
|
||||
|
||||
use clap::StructOpt;
|
||||
use tracing::span::Span;
|
||||
|
12
leo/main.rs
12
leo/main.rs
@ -77,11 +77,11 @@ enum Commands {
|
||||
},
|
||||
// #[structopt(subcommand)]
|
||||
// Node(Node),
|
||||
#[structopt(about = "Deploy a program")]
|
||||
Deploy {
|
||||
#[structopt(flatten)]
|
||||
command: Deploy,
|
||||
},
|
||||
// #[structopt(about = "Deploy a program")]
|
||||
// Deploy {
|
||||
// #[structopt(flatten)]
|
||||
// command: Deploy,
|
||||
// },
|
||||
}
|
||||
|
||||
fn set_panic_hook() {
|
||||
@ -138,7 +138,7 @@ pub fn run_with_args(cli: CLI) -> Result<()> {
|
||||
Commands::Clean { command } => command.try_execute(context),
|
||||
Commands::Run { command } => command.try_execute(context),
|
||||
// Commands::Node(command) => command.try_execute(context),
|
||||
Commands::Deploy { command } => command.try_execute(context),
|
||||
// Commands::Deploy { command } => command.try_execute(context),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 5b0842e447b4e1f92f4bcd22824ed5e12c51c8db145d1541763d10ad3dc1f37a
|
||||
inlined_ast: 5b0842e447b4e1f92f4bcd22824ed5e12c51c8db145d1541763d10ad3dc1f37a
|
||||
dce_ast: 946b0fe81e942060d870c228afb1a31c42501fb8f9c481d35d7908b226af5cbe
|
||||
bytecode: 31bab7a79a7dfdfbcd4a7a3f26cd813b48d7c1438dec3fd4905a81845161dba1
|
||||
bytecode: e434c09cee27a5dfb5a4e9e9fd26aa2ba6e7f0653fad3a4f2a7d85983ba559c9
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: c1b6954bff1ce18c0bb3be1cd6392a554a15989c90939c99e375221b1003e3b7
|
||||
inlined_ast: c1b6954bff1ce18c0bb3be1cd6392a554a15989c90939c99e375221b1003e3b7
|
||||
dce_ast: c1b6954bff1ce18c0bb3be1cd6392a554a15989c90939c99e375221b1003e3b7
|
||||
bytecode: b192f4b7f52da46a22cec3aec7e8c14b6e3fad7c40b9d0c0990255902fb596ef
|
||||
bytecode: da1b0a83a17b801368b0a583b158d88d9d807a33000c8e89e82da123c8041aea
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: f9458e7824444415aa9f3feec4924461f49dee915429e63dec244806d3812722
|
||||
inlined_ast: f9458e7824444415aa9f3feec4924461f49dee915429e63dec244806d3812722
|
||||
dce_ast: f9458e7824444415aa9f3feec4924461f49dee915429e63dec244806d3812722
|
||||
bytecode: 4903abf35d22e4264aae4bf26b908108d11d981d069c247793cea817dd8851a7
|
||||
bytecode: bde2653fac0393940c5400272e53492228206e50abb36ce080b95043003ee976
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 1041763865cf86407bf30dae2b003ec9094e91e79c3e5b493b54fbd67cdd8f24
|
||||
inlined_ast: 1041763865cf86407bf30dae2b003ec9094e91e79c3e5b493b54fbd67cdd8f24
|
||||
dce_ast: 1041763865cf86407bf30dae2b003ec9094e91e79c3e5b493b54fbd67cdd8f24
|
||||
bytecode: 5cbdf4a6a290f80540d2653153c57495eaf45432bc7ce44d52af2b5d0594951c
|
||||
bytecode: c0b90b7f7e80041dc1a314c1a87290534936018fb001c6e1291266a02393c6f2
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 4e7759584ade51a19ff90284e5ee1ac91af6dad5cd966568b708ead553a8a4bd
|
||||
inlined_ast: 4e7759584ade51a19ff90284e5ee1ac91af6dad5cd966568b708ead553a8a4bd
|
||||
dce_ast: 4e7759584ade51a19ff90284e5ee1ac91af6dad5cd966568b708ead553a8a4bd
|
||||
bytecode: e3deaf24a91bcb77628f7af29d4ad6d0ba67215617d6cfe753168543123ce7d2
|
||||
bytecode: 134904b86b96581876c2ca0c6ead651dda0dc9f2fb6dc583400133410b7deede
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: de891bab08a157399fdceeeccc7c3d4fd70cc3f75d1ca694a4fcd0344fdaac20
|
||||
inlined_ast: de891bab08a157399fdceeeccc7c3d4fd70cc3f75d1ca694a4fcd0344fdaac20
|
||||
dce_ast: de891bab08a157399fdceeeccc7c3d4fd70cc3f75d1ca694a4fcd0344fdaac20
|
||||
bytecode: d0d3f79c32e6cb17c98afa2f1d4861d0f71d7f805a87712b3491ef0a9e1b4892
|
||||
bytecode: 56a9fa48a00d1b38b6f60a93ef2168b2c0ce9c23ba3cb7bffa40debfc1b16180
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: b39344c70e1a23869b236146ace198addf0801b348deedfb3e4ff1e3c4ace904
|
||||
inlined_ast: b39344c70e1a23869b236146ace198addf0801b348deedfb3e4ff1e3c4ace904
|
||||
dce_ast: b39344c70e1a23869b236146ace198addf0801b348deedfb3e4ff1e3c4ace904
|
||||
bytecode: e742ac3b95a8971f2018963aba6d915ea53205c21443d0b11ad52a42ad443b97
|
||||
bytecode: 2332d5b7ed9910dc65c885e1aeedbbde00e02d95a55caa300a9cb72456707034
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 84fd34b95b75f6d72b28164a9cb2ac80fa4149564c8c187b0ead1e14d2299a63
|
||||
inlined_ast: 84fd34b95b75f6d72b28164a9cb2ac80fa4149564c8c187b0ead1e14d2299a63
|
||||
dce_ast: 84fd34b95b75f6d72b28164a9cb2ac80fa4149564c8c187b0ead1e14d2299a63
|
||||
bytecode: 1db874ad15d9bb70df7372ed3250cc6d0f65992e17788cd90c656ef1e1ceb63e
|
||||
bytecode: 990eee0b87d70df046bad969201ad8afabff10162eb70c00f837fde81fed4104
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 1e61c9d9ccdae7fb4aed4d7332538438839bef08a322f52fabcf46eac7bfc9c8
|
||||
inlined_ast: 1e61c9d9ccdae7fb4aed4d7332538438839bef08a322f52fabcf46eac7bfc9c8
|
||||
dce_ast: ab80f3a28ba9de58b165074c3ffae7e5be48e721bf17219252cecc0a6fb8b6e4
|
||||
bytecode: fedea8c873d237103657ba0902968bf5be3e854c95b2720b28fda529c5b87ff1
|
||||
bytecode: bb260232bbd0ccede368961a31abeef5edc7e00cab3348b4b8518d4e5798a6b5
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: cf5034c292702654bd282c10c8d1abafed8ed328f8e6cd0a01b286438809afd5
|
||||
inlined_ast: cf5034c292702654bd282c10c8d1abafed8ed328f8e6cd0a01b286438809afd5
|
||||
dce_ast: cf5034c292702654bd282c10c8d1abafed8ed328f8e6cd0a01b286438809afd5
|
||||
bytecode: e859520fd52dbdf69b14a3c3d9bad64bf6165084fb949912224eda3ccab9b638
|
||||
bytecode: c3a0c03f4324a6dd6baea42e664ffad91868714739e03525dcbc968582007ceb
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 7a2b73a748d86babab5ca7a4f9e513cfd028dcbadc7df8baeb7774ffb54c1b43
|
||||
inlined_ast: 7a2b73a748d86babab5ca7a4f9e513cfd028dcbadc7df8baeb7774ffb54c1b43
|
||||
dce_ast: 7a2b73a748d86babab5ca7a4f9e513cfd028dcbadc7df8baeb7774ffb54c1b43
|
||||
bytecode: fdc5659b97d4dbfea710ca848dcffa29bcd4da3a7a54739fb916e5292284a1a4
|
||||
bytecode: 2d96971b7ff11cd865ed1b79ca417d062b970f3442cf9e6f53f033b5f258c556
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 083a9af2e592de0c827b15230cd2307daae4b90e324e35714f474d50cbb59162
|
||||
inlined_ast: 083a9af2e592de0c827b15230cd2307daae4b90e324e35714f474d50cbb59162
|
||||
dce_ast: 083a9af2e592de0c827b15230cd2307daae4b90e324e35714f474d50cbb59162
|
||||
bytecode: 9006475518263541b3a855db6907377b638ef28f2a44caf4e26db7991c3b58ef
|
||||
bytecode: 3ff716b96c532801f4fa5310f4eedf8f96fe15bd7db3bf087e7b64a161153945
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 91862d403b538c1100f31dc5979ffee097a3c71173315bda9b00e2b2fbd246cb
|
||||
unrolled_ast: 91862d403b538c1100f31dc5979ffee097a3c71173315bda9b00e2b2fbd246cb
|
||||
ssa_ast: 869edce87a429184f914c6ff72592de2e8dc1395f8b413237857c4111a796d39
|
||||
flattened_ast: a2b862ac405e65f5dd9258cff25237c23ea457bfa8b5c449da49248d326f28d0
|
||||
inlined_ast: a2b862ac405e65f5dd9258cff25237c23ea457bfa8b5c449da49248d326f28d0
|
||||
dce_ast: df34074e0922066553939fcbf28b572addaaf4bcd83f6cd42222780f1ec6622b
|
||||
bytecode: ba841e355e57f9ad4c4a01b358d4e21d960453a5f0590715b16544c7cdde20b4
|
||||
- - initial_ast: 4a07b869cb8de3d550e632e5522b289c449abb968b282f5fa3f4076dcb4dda0c
|
||||
unrolled_ast: 4a07b869cb8de3d550e632e5522b289c449abb968b282f5fa3f4076dcb4dda0c
|
||||
ssa_ast: f18a586a5733c38b399941c9502093cbb08fd09d9c0f1daefeb4f3fc4e396bfe
|
||||
flattened_ast: f10ac6c175784980ffe81b9d14d5abf39288cd6a55c6982b3cb32ed3e6b36336
|
||||
inlined_ast: f10ac6c175784980ffe81b9d14d5abf39288cd6a55c6982b3cb32ed3e6b36336
|
||||
dce_ast: 22338b00245ad994428d0e7f3cdb4596c3253aa89cd547eb1da68d17cc7daae1
|
||||
bytecode: 9929c4c4138f54a98a47a3de536f73a211cf490539d1f2f55cd6878d468d7b56
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 3264d91e7918b4576be9b02519ad678de98bd28789f866076a2db87f8bf6de13
|
||||
unrolled_ast: 3264d91e7918b4576be9b02519ad678de98bd28789f866076a2db87f8bf6de13
|
||||
ssa_ast: bc7b8721cbfb437ea6eb609ec335e9e22ddabb3f9240488801f9f193cf14b403
|
||||
flattened_ast: b237061bd9ae5a830947d80f051bbee4e7ced839dee6a1fb28f868aa3c7a4537
|
||||
inlined_ast: b237061bd9ae5a830947d80f051bbee4e7ced839dee6a1fb28f868aa3c7a4537
|
||||
dce_ast: c67c332f52173ca72aa22ee4a365ce953f9b4f18767ecaba69bd2c7184a0fafe
|
||||
bytecode: 4f6a5b2268ffc7810d1d7fca88c7d7ec7c92b080fc2c752e3faf737f37a58e64
|
||||
- - initial_ast: 9b05ccb827d05aec4633080aec05b1cf0b00a44e408badb0ba2903b20de371a0
|
||||
unrolled_ast: 9b05ccb827d05aec4633080aec05b1cf0b00a44e408badb0ba2903b20de371a0
|
||||
ssa_ast: fe53b8620fcbd33724ae55b400fa8670b159d8895827179fb1f359c6b4019af0
|
||||
flattened_ast: 8383bea2712e3923e51964484d2572bbab5bf6b7b5f2482f3de75d0725982729
|
||||
inlined_ast: 8383bea2712e3923e51964484d2572bbab5bf6b7b5f2482f3de75d0725982729
|
||||
dce_ast: 5769dea7f3bb04d04838d6b1a00a76ad971905b3aed24c1b8b272e8a0eebbaf4
|
||||
bytecode: 4b256b94eba361efe85a1d3a0504459d30627a3fe3dc565a77563b6c3fe56485
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: f7ace4c6722a161a5d16489b3e0fa4734bae59f500fbe619bcade17e3cb559e7
|
||||
unrolled_ast: f7ace4c6722a161a5d16489b3e0fa4734bae59f500fbe619bcade17e3cb559e7
|
||||
ssa_ast: 649adcba3bd743536eab0aaf9d81ca0b72911c7b9b5d83f23c73a481102c36e0
|
||||
flattened_ast: 133fcd28e2d6767664071a0af992bc9601e481ac2ea9f17faf624f144c43bc4b
|
||||
inlined_ast: 133fcd28e2d6767664071a0af992bc9601e481ac2ea9f17faf624f144c43bc4b
|
||||
dce_ast: 3df14b9911324d85dd9f114e9db7ebb9f163f5dbac6669c033431c01b44758e0
|
||||
bytecode: d323d7074e8595ad95520b70580a5c41a57541aac1eb7aa680e674fb699f90ed
|
||||
- - initial_ast: f0870766c47c47ae2f0c57251e84b227fe308f3e27cd05843219857a1bcedd7e
|
||||
unrolled_ast: f0870766c47c47ae2f0c57251e84b227fe308f3e27cd05843219857a1bcedd7e
|
||||
ssa_ast: d9b742f5fe13d742e5ba8bc3f2da452ca403457fdd50d61bbe2c6c791317a3a3
|
||||
flattened_ast: 77d87dd7b9b70c26962b9211778d3e06eb409e3984b1b03f2a859a35c08f7116
|
||||
inlined_ast: 77d87dd7b9b70c26962b9211778d3e06eb409e3984b1b03f2a859a35c08f7116
|
||||
dce_ast: 0e77c77136906cc81efc8cf2a72058963c85253ba4c901c6a404b64671983795
|
||||
bytecode: 44dc9d33e1227a0be1b7d0c1cbbcdc57c08e769c4e56990a6e12bc01c7e6c0fa
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: fae17dce96224c854538e0acdd1d2ccfd1755aec4e48913d67febd5155025f32
|
||||
unrolled_ast: fae17dce96224c854538e0acdd1d2ccfd1755aec4e48913d67febd5155025f32
|
||||
ssa_ast: c5ef5cf3a66b8fd09c4fb651bec9feec382af6aa025ca54f2514fcba1b781d30
|
||||
flattened_ast: 3dab7bf9e471da6c3f524c510c64c6b5a8850ea4e4b644f3a5513c9d5fcf622a
|
||||
inlined_ast: 3dab7bf9e471da6c3f524c510c64c6b5a8850ea4e4b644f3a5513c9d5fcf622a
|
||||
dce_ast: e0a7d58415cc69357806e74261e06204cbadbdd6acbecf3c80c7abd3a77be1f1
|
||||
bytecode: a838bb972d5c9fab64c81f1c874d90795edc4a6385b524fcf6f90d8513e2a05b
|
||||
- - initial_ast: 748fbec820d27e116abf5a78230df78bd75b3a90a1dd1ff26e7baa0209e4331f
|
||||
unrolled_ast: 748fbec820d27e116abf5a78230df78bd75b3a90a1dd1ff26e7baa0209e4331f
|
||||
ssa_ast: 4be5c09a729ca14c2e5feb62330ddbbd2ce218ef65e64cfba8c4df6e928634b4
|
||||
flattened_ast: bb4aa2f6741a3018e60d109a8849cb0db9a4d8bc8455d7fab28f6f251c0a235f
|
||||
inlined_ast: bb4aa2f6741a3018e60d109a8849cb0db9a4d8bc8455d7fab28f6f251c0a235f
|
||||
dce_ast: 6d9f949ba1756569c7df636bfe3ea6fa99691510121d5e7243b5da4fae598355
|
||||
bytecode: 658a56af137ceb28a2d375453047d014c1ce2ced005ac3c00d4cca9b0b4f384d
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: ddc90f881ec1f45741301812d26aabd1901d0d471d6448e96737b5c9e3851ab3
|
||||
unrolled_ast: ddc90f881ec1f45741301812d26aabd1901d0d471d6448e96737b5c9e3851ab3
|
||||
ssa_ast: 7dccc1dc94e6b05557cdf294945513116856f6dd7c6e0c8b46b1089d453188bd
|
||||
flattened_ast: ff3db8d357defae10ab07f35aa1df3b84dddad1453da60463c97cf1f61492147
|
||||
inlined_ast: ff3db8d357defae10ab07f35aa1df3b84dddad1453da60463c97cf1f61492147
|
||||
dce_ast: f86eaa7fc6bf849868a5f9f0279889c7429c98413ff38d2f8667f74a55d9ebb9
|
||||
bytecode: 12b55db95d5f6e760a8ebb0604264fb1b09b771d247d093eaed4dec8c28a579b
|
||||
- - initial_ast: c14a3a02de49f39f4830c3ac8ab7e9211775c9167a0fb18b448272d00506550e
|
||||
unrolled_ast: c14a3a02de49f39f4830c3ac8ab7e9211775c9167a0fb18b448272d00506550e
|
||||
ssa_ast: fe3dc9ccbd0e7764ffffe162397efe40a7a3c2c03adca293a1047d7e070a2d5f
|
||||
flattened_ast: fd62621c1e71b83c6af794643815c0f5a95fce09ad8ab8f69a4e0116aa182a85
|
||||
inlined_ast: fd62621c1e71b83c6af794643815c0f5a95fce09ad8ab8f69a4e0116aa182a85
|
||||
dce_ast: 92ce3e89a36cf48a64832fecb1c8e049a60cab9b4c892bb467894d35da6f7957
|
||||
bytecode: 5f0519511cf81d4155bc8186812e59861e16cf5d8f1a2e6a87f2acf6877d425b
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 4fe2842db5a366b9cc40a7d61e5f601471ab00369d754eeb06c63063b166eb0b
|
||||
unrolled_ast: 4fe2842db5a366b9cc40a7d61e5f601471ab00369d754eeb06c63063b166eb0b
|
||||
ssa_ast: 907da2b9128857218e5c3a6f94e66f6fea60002fb84edfc152737a02cf7dacd1
|
||||
flattened_ast: 75c3f273bfeb27f285138e30b1cbc97f1b45d310dd8bd59278bea1c44ae66f6b
|
||||
inlined_ast: 75c3f273bfeb27f285138e30b1cbc97f1b45d310dd8bd59278bea1c44ae66f6b
|
||||
dce_ast: 5ffda7837ed85713d10352862a479bfb31165902a21de31c849c25cfb8e6657a
|
||||
bytecode: fca69f7905d164b970b57988810e4629b009cdbfc1ad5952459ef579a40b616c
|
||||
- - initial_ast: 70cfe685cb59d5f729016d933776757a149cc40e15082adb9a8a33c49471b29b
|
||||
unrolled_ast: 70cfe685cb59d5f729016d933776757a149cc40e15082adb9a8a33c49471b29b
|
||||
ssa_ast: 6869b361fcaf9820c66a413021e228b7e401e3c56dda5561ad6b521f715f9e7c
|
||||
flattened_ast: bc27e72065c76ae99982f2eaa27447c067e47e50b3b6e1c4c8f64ab865501840
|
||||
inlined_ast: bc27e72065c76ae99982f2eaa27447c067e47e50b3b6e1c4c8f64ab865501840
|
||||
dce_ast: 3097f0d4b705ad5cfc6b50c3a06ebf98a0269a8fc1f4d066caa6f2897fe65b99
|
||||
bytecode: c7b632582f3311328e4abde2ef72f034d56195254f794463a0d720d832b5ac1d
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: d70daf2abc3e9a8ba4424c3c370c2037c973e05c2048ed0dc1d7ff72f14bc60a
|
||||
unrolled_ast: d70daf2abc3e9a8ba4424c3c370c2037c973e05c2048ed0dc1d7ff72f14bc60a
|
||||
ssa_ast: 782104fd26bd70f18b2a7baedd9594ffa0c7879e0a8e9fdfd8e66f03b51102c6
|
||||
flattened_ast: 8e4b0058f7016f503300ac68760852dff28900eaa79215926464b924665ebcb6
|
||||
inlined_ast: 8e4b0058f7016f503300ac68760852dff28900eaa79215926464b924665ebcb6
|
||||
dce_ast: efdd14f5229f37fcf190afeecde9c42699a7a936c219cb6f90be3b31cbf5bb87
|
||||
bytecode: ed946f317a1fbdd2a8f9a2274d8cb72326308007df1d2f02d82893fe00453844
|
||||
- - initial_ast: b64518163dfdadcbb229a7c36cb49e7f256ef15742a24124367327356ce1aa2e
|
||||
unrolled_ast: b64518163dfdadcbb229a7c36cb49e7f256ef15742a24124367327356ce1aa2e
|
||||
ssa_ast: 32c3e70f66baca266bba2eaa786b099cdb9148a1ac1993fa9f9bb3dc702baaa9
|
||||
flattened_ast: 62a50853b2bd04970ed4178534271dc0e41087bc8f56ada2f36c5126491d05e1
|
||||
inlined_ast: 62a50853b2bd04970ed4178534271dc0e41087bc8f56ada2f36c5126491d05e1
|
||||
dce_ast: 5d99cb57111ce4be3917714d8a5f75aa0a64791b3c1e7a2997554a4852bab1e7
|
||||
bytecode: bc09fb906965357015431b53e647685324a17c5eedcd9ac8c6023a60fd44657f
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 8a14b07c6c839a99d03dd0500335bda9fd2b8deec52b42edaf4ddf3aa3735037
|
||||
unrolled_ast: 8a14b07c6c839a99d03dd0500335bda9fd2b8deec52b42edaf4ddf3aa3735037
|
||||
ssa_ast: ea512a03053a33e37bb817d6c4592043329e98e1f9a115fd101d74ccd239e2c2
|
||||
flattened_ast: 68fd19aa7e43e46b9ffa4f23e518e0b3d818b9ad10f8521c3be324241fb36521
|
||||
inlined_ast: 68fd19aa7e43e46b9ffa4f23e518e0b3d818b9ad10f8521c3be324241fb36521
|
||||
dce_ast: 898d04af13dec567b07cfea58295650ffc76b709d617c7545632ebc6a550aefd
|
||||
bytecode: 15c8e5674fa814192d9b8f836c92615685079bf9fb97bbfca8e3d5ca836a1cdf
|
||||
- - initial_ast: d1e8ca5d21a00ac0316c5dbc6b32ff9b8aaf6350f21a79d563159c95a0431968
|
||||
unrolled_ast: d1e8ca5d21a00ac0316c5dbc6b32ff9b8aaf6350f21a79d563159c95a0431968
|
||||
ssa_ast: 2669eea4c9d93544432f857bf774d4a98954e7a9e72d363b613aba902cb048df
|
||||
flattened_ast: 9d6f650b19bfd9079c8755675adc806544e74373eb5473d1f74a67805da28234
|
||||
inlined_ast: 9d6f650b19bfd9079c8755675adc806544e74373eb5473d1f74a67805da28234
|
||||
dce_ast: 36718215f4ec56250a8f62627ec0baf66a544d99cd446c2fcf94c24805c51d43
|
||||
bytecode: 1daea9ed03b974a37a1bc3363dd2253e33d8ba5933e60f620467b712c33386f0
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c57c36b9b59e05c91849e91969a79474d5fcb49d284be8140ffaac4746ae7191
|
||||
unrolled_ast: c57c36b9b59e05c91849e91969a79474d5fcb49d284be8140ffaac4746ae7191
|
||||
ssa_ast: 586af29b0b79edf5f19a4bd494d8428f22a87f851119d7f74eab9b535810468d
|
||||
flattened_ast: f72217bcb7185ae66114addb89c1bcf61da6ff200ece88309aa50dc3f5ebefd9
|
||||
inlined_ast: f72217bcb7185ae66114addb89c1bcf61da6ff200ece88309aa50dc3f5ebefd9
|
||||
dce_ast: d5dad9bef9df7ffdf27685563189b9900543e153761cf5ded8e16a58b48dd07b
|
||||
bytecode: 52babd5fc1693c9b41d1f8e26d7c5c91f27c9409c8a49c56374c14f068a69715
|
||||
- - initial_ast: 1c13802720b3a14ccb2b0df3a1a22dbe8ebea504b78d222bc16d7022d9cef670
|
||||
unrolled_ast: 1c13802720b3a14ccb2b0df3a1a22dbe8ebea504b78d222bc16d7022d9cef670
|
||||
ssa_ast: a2ac60bce9a712bf60e0f88214354eb87ac8bae605e72e151960e4461ca895ba
|
||||
flattened_ast: ae4389c5f39e2b7f0dba71a8da6b1de1679e8f49c9c74b5b9cc12c9863e0750e
|
||||
inlined_ast: ae4389c5f39e2b7f0dba71a8da6b1de1679e8f49c9c74b5b9cc12c9863e0750e
|
||||
dce_ast: f540193e45d33214f6515429a42de05a811504f1fc611021faaa92ab4cf34897
|
||||
bytecode: 49169104a3029770de8a49b3dcd05a47a6f85a296ffd8c4843af2f24d52e4ed0
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: c00a32cd00345e923e87dcd16427c9f2ec733022431e38cceefbb5ab6143b161
|
||||
unrolled_ast: c00a32cd00345e923e87dcd16427c9f2ec733022431e38cceefbb5ab6143b161
|
||||
ssa_ast: 29ecb3770403a15ee05a695260ebc6f7b8e313b4614e3a1f06de34b4d03ff147
|
||||
flattened_ast: 9711e4d72e2e9e85b24e3b4b3e73cc939a05a5846733c0eb15dab5c5b54a054a
|
||||
inlined_ast: 9711e4d72e2e9e85b24e3b4b3e73cc939a05a5846733c0eb15dab5c5b54a054a
|
||||
dce_ast: 3a8d12872135e283b8f21c4207fa37fe7969ea75b810aa227aeeca69c90a1a5a
|
||||
bytecode: 2dd437da2efd160fbba1cb573e9ac61d046ff0afbbffd8f98fa1aebefdde98c5
|
||||
- - initial_ast: 26a6fa12be337faaa50d13e8b9734491a9b4544c2eacc1780088af5f43022819
|
||||
unrolled_ast: 26a6fa12be337faaa50d13e8b9734491a9b4544c2eacc1780088af5f43022819
|
||||
ssa_ast: f0da78468c17cff948146d18de76afc220427b7373de53e5690156e85a761032
|
||||
flattened_ast: e12c71864073591a0083d0deb3c603c9b92d61d0c85d0ef20d00834f32695cfc
|
||||
inlined_ast: e12c71864073591a0083d0deb3c603c9b92d61d0c85d0ef20d00834f32695cfc
|
||||
dce_ast: 7beb9834c34c395899d3553b125c7363018a019a4d1e5139bde7fa6aad1d787b
|
||||
bytecode: 1b79eff17f96fad334dc6dcdfcea3f146ac4dcc3bb71cafbe7031e9a70befd63
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 4eaa587c05eb4f4a65f33d94cd12a1ce47a55263726b7619578846c620735b3d
|
||||
unrolled_ast: 4eaa587c05eb4f4a65f33d94cd12a1ce47a55263726b7619578846c620735b3d
|
||||
ssa_ast: 3e1a3d03f465a60b2ceb2fc480551d9d498beb758a6b378ae6558117ec2955a7
|
||||
flattened_ast: 2448c3c0819a99113f4acb509371009619592a984911b836f9787a386cf1e617
|
||||
inlined_ast: 2448c3c0819a99113f4acb509371009619592a984911b836f9787a386cf1e617
|
||||
dce_ast: 0fd6329efebd5d284865f633a0459df53b14e8cee46ba18004ac90038c79b856
|
||||
bytecode: c4131bb0900a47f3b000722e7218a8b030927e34f2952bed289bc5fe6437a995
|
||||
- - initial_ast: dc173a1cfc3721e31cf6ab23f3ec05b049b8b36c1f20bbbf384d0ef08a8eeced
|
||||
unrolled_ast: dc173a1cfc3721e31cf6ab23f3ec05b049b8b36c1f20bbbf384d0ef08a8eeced
|
||||
ssa_ast: c596ff010c5cf146f5709e73bc7a37ae9f25b572b5e08efa27bf1983c63b7b16
|
||||
flattened_ast: 1902e033f0557a18eeebdcf6af2f925b3481d78c802b08cdbc382c918e5f1289
|
||||
inlined_ast: 1902e033f0557a18eeebdcf6af2f925b3481d78c802b08cdbc382c918e5f1289
|
||||
dce_ast: 2de077f9e262070e8fb3f8551539790e01e1f1c55d26a051e8baf7b8ecd6ec38
|
||||
bytecode: ba1005b5009f289e977d1a7c57ba41c8a5ca6fb35bcca094a7b97cb0a729a77b
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 8693aac7091d75fe65a52352decb2ce24e225dae9396cb45809575f7c3cbd8d9
|
||||
unrolled_ast: 8693aac7091d75fe65a52352decb2ce24e225dae9396cb45809575f7c3cbd8d9
|
||||
ssa_ast: 5a33864a3f91c0d4a63171ed36ef709b7e75593a3181b4ed3f11be873ce2b9a2
|
||||
flattened_ast: 8a13f93c69d995ea32ab518a4287d77dd9e37e4e1f15fd257361c58a0f853e7b
|
||||
inlined_ast: 8a13f93c69d995ea32ab518a4287d77dd9e37e4e1f15fd257361c58a0f853e7b
|
||||
dce_ast: dd061aec3f3a5e3ae3ee930dcdf543adc041f27d5c9d3004f43deff18c3e68ee
|
||||
bytecode: 39222c7508c1ea4a59a42f8a65904f2ec657bbb2d3e8d750a7a475816a2bc2b6
|
||||
- - initial_ast: 3da30fc98bd9391ab5f3dc3d6ed6855a720a80ce99a268360044295077a6a55d
|
||||
unrolled_ast: 3da30fc98bd9391ab5f3dc3d6ed6855a720a80ce99a268360044295077a6a55d
|
||||
ssa_ast: 786b929593cd831367d8789ce101e4c3aa2825ac5e573ac53a2519ce464de0bf
|
||||
flattened_ast: 6cd2db5cbc9b5ccb71739c30c2e117ae366011a45a9ca6f0b35432b40b40ece4
|
||||
inlined_ast: 6cd2db5cbc9b5ccb71739c30c2e117ae366011a45a9ca6f0b35432b40b40ece4
|
||||
dce_ast: 2d2e24c010ca22444d96468659af0248ce80bf2356a7e147b59dca1f0dd0bcf6
|
||||
bytecode: 2a7413652334cd2069040cd094fcbba5101768525829bfef77f42b9640caa92e
|
||||
warnings: ""
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- "Error [ETYC0372046]: Invalid type `u128`\n --> compiler-test:5:41\n |\n 5 | let a: group = Pedersen64::hash(1u128); // Pedersen64 hash returns a field type\n | ^^^^^\nError [ETYC0372003]: Expected type `group` but type `field` was found\n --> compiler-test:5:24\n |\n 5 | let a: group = Pedersen64::hash(1u128); // Pedersen64 hash returns a field type\n | ^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
- "Error [ETYC0372007]: Expected one type from `boolean, integer (up to 64 bits), string`, but got `u128`\n --> compiler-test:5:41\n |\n 5 | let a: group = Pedersen64::hash(1u128); // Pedersen64 hash returns a field type\n | ^^^^^\nError [ETYC0372007]: Expected one type from `group`, but got `field`\n --> compiler-test:5:24\n |\n 5 | let a: group = Pedersen64::hash(1u128); // Pedersen64 hash returns a field type\n | ^^^^^^^^^^^^^^^^^^^^^^^\n"
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 5b68dd17af0f5bab6f5cc67f2b47a35760041ef9ff4df7ea8f010559bae5781a
|
||||
unrolled_ast: 5b68dd17af0f5bab6f5cc67f2b47a35760041ef9ff4df7ea8f010559bae5781a
|
||||
ssa_ast: ef60c984ccfa580d1285dbbfe0d43553f1fd22b2d3a23f677e41a6d9943135ba
|
||||
flattened_ast: e2383f7bb4b70472e366c8285f017807b15eb2bffb747ff31cfcf4078318f186
|
||||
inlined_ast: e2383f7bb4b70472e366c8285f017807b15eb2bffb747ff31cfcf4078318f186
|
||||
dce_ast: d48a8f76789c725ba2b15efce543d5a575f24866642ac722b31c759def6040e9
|
||||
bytecode: ec61486b3488918a8a8db406b9d6c8a4fd73b865c7add4cd2646b6ed4738c648
|
||||
- - initial_ast: fe204baf38cb41c3b3ee2f4c35e5fcd3e899d99d8301c5f7e37d4d6eb208cab2
|
||||
unrolled_ast: fe204baf38cb41c3b3ee2f4c35e5fcd3e899d99d8301c5f7e37d4d6eb208cab2
|
||||
ssa_ast: 041e817950dc97bfd5c21a62710d1433f3c4866d1fbf4866226e622c610a793b
|
||||
flattened_ast: e42d5f74d346c02ce76a0195c5b42afda07abe0b4f159ceabf9a7fae5b4037ee
|
||||
inlined_ast: e42d5f74d346c02ce76a0195c5b42afda07abe0b4f159ceabf9a7fae5b4037ee
|
||||
dce_ast: 54a0ef3e7b09076a1150ab30db531462a0519512dadc1b6e3184771bb9871c75
|
||||
bytecode: fa10122f9c350abf2daed9e006d4054d7f8625a9d7b89391342016b1bef0de68
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 9c2d420ea86a2611aed31072a96be5973fe931cb5208834dbbaaa85832dad479
|
||||
unrolled_ast: 9c2d420ea86a2611aed31072a96be5973fe931cb5208834dbbaaa85832dad479
|
||||
ssa_ast: c1b75e3e3caf0094fc3a3a955dfbfbd844d86a9da4ffbad5646cf2d079c8fc49
|
||||
flattened_ast: 42ab17eace07ba9fa174e1dd7f509045476ae4e3dab1393fe302973880bc4da8
|
||||
inlined_ast: 42ab17eace07ba9fa174e1dd7f509045476ae4e3dab1393fe302973880bc4da8
|
||||
dce_ast: c29e475b3798613746f0aca803383facd5f988c0fe619ab155ae55baed2fd400
|
||||
bytecode: 36b4ead8db1862fcd7831096b07f40256c01e8039c41be29c007a334cd2343f9
|
||||
- - initial_ast: fb08ce9dab912d404c0e05da60370787c4f20f6dae978dcf284a97576880fcbd
|
||||
unrolled_ast: fb08ce9dab912d404c0e05da60370787c4f20f6dae978dcf284a97576880fcbd
|
||||
ssa_ast: b8d5fe10404f61380e52cbf86f25a2b4d0ba6aff190847cbe9ba27c1414c2dc4
|
||||
flattened_ast: e5456a70a1c7ddef8570de1f6bb362c91223cb468debdaad3875b51a1f8328d8
|
||||
inlined_ast: e5456a70a1c7ddef8570de1f6bb362c91223cb468debdaad3875b51a1f8328d8
|
||||
dce_ast: bf2279949308e7cdce4b4cb7de8380779a291f496767ed12e646c19aeb07ed36
|
||||
bytecode: 0c5118ed3ab41bc82ea097ca6aba77d2e0f607ae4aa764b17805a840b209a5d1
|
||||
warnings: ""
|
||||
|
@ -2,10 +2,11 @@
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 417887bbb9a8fddcc52848e4517ffd59dcaaf35512e1166df3838f0a15f7ac74
|
||||
unrolled_ast: 417887bbb9a8fddcc52848e4517ffd59dcaaf35512e1166df3838f0a15f7ac74
|
||||
ssa_ast: 95bf4aa7a18c4e152ae24292bcba2cef5c3fc2c7bea6cdc80d146f3e31ebe984
|
||||
flattened_ast: a698ca5479fd0b3b6e7a4d55f9f0c06c1390f920145357a2e3e46e8b453f5ad5
|
||||
inlined_ast: a698ca5479fd0b3b6e7a4d55f9f0c06c1390f920145357a2e3e46e8b453f5ad5
|
||||
dce_ast: b2cbcf19bf6f16d14311ac2c98820ca4ac8d34c2a14bf69784ab5f15114e297f
|
||||
bytecode: 7353ae74ad6fd49fadd68e4f452d31569c2c09189cf5840ff49af032a7aab3cd
|
||||
- - initial_ast: 4189522cc485dc368b64196ab39a6b812624ad681bd720fd97f258e968186a9f
|
||||
unrolled_ast: 4189522cc485dc368b64196ab39a6b812624ad681bd720fd97f258e968186a9f
|
||||
ssa_ast: e7b20ccc7d4f94dc36aa03cfdf31cff456aaaa936e166df578fa8f14b14428d2
|
||||
flattened_ast: 1d1965e1d7226bd8b4141a6d4aad245753cb07b8ffd59a7b8abc7fa09ff2a02f
|
||||
inlined_ast: 1d1965e1d7226bd8b4141a6d4aad245753cb07b8ffd59a7b8abc7fa09ff2a02f
|
||||
dce_ast: 5960e205ada7855478b2bb6b88620d0f6a5a813a54f426ac4afa20cf508ced7b
|
||||
bytecode: d73b8b26c914288ca2cff06f5718cf8f4d3eb288c6310783d7edf98a43985772
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: bc4a52e6fb7998c2a8a454306e75598177546db8f32a5a79e95ead68abc72880
|
||||
inlined_ast: bc4a52e6fb7998c2a8a454306e75598177546db8f32a5a79e95ead68abc72880
|
||||
dce_ast: bc4a52e6fb7998c2a8a454306e75598177546db8f32a5a79e95ead68abc72880
|
||||
bytecode: 9a1e5bb7b8d932d4afd347a856bfb38db144771f49a0d9589ef14236338e3dcf
|
||||
bytecode: 651a250bda995df00cf3b4659d1ea35912ed94da32b5d487677dead9126b5d69
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 9c98dfcdcb403983efb0b1078246ca9e3c3e8fe913f6ceabbd9a87b63f3fc3a4
|
||||
inlined_ast: 9c98dfcdcb403983efb0b1078246ca9e3c3e8fe913f6ceabbd9a87b63f3fc3a4
|
||||
dce_ast: 9c98dfcdcb403983efb0b1078246ca9e3c3e8fe913f6ceabbd9a87b63f3fc3a4
|
||||
bytecode: 230d4f2bda3933eb4fafc4dda4ce0087e74e4cbd9c65349746da561cbb3f99da
|
||||
bytecode: 587770d63e2d2fe866f99683df9a32da50b718ee3a92aec0d9491cbb8569b80d
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 0840cf638ec3532c7702d10bbbfcf2fbfc8c8f7c54e532acb4ac46cbb7c8ed61
|
||||
inlined_ast: 0840cf638ec3532c7702d10bbbfcf2fbfc8c8f7c54e532acb4ac46cbb7c8ed61
|
||||
dce_ast: 0840cf638ec3532c7702d10bbbfcf2fbfc8c8f7c54e532acb4ac46cbb7c8ed61
|
||||
bytecode: fa960590c979aea4bdfe07b7d37060bb593f73f745974241e2db578bd7ba2ced
|
||||
bytecode: 8076383080c6f141d8c6038360d4c9494a44f39b20f85614faf57bb7f6e3a10d
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: f1d531bbe1b2e0bf0f30a1f7e86cce88c834fee9eb4d06548508907ad5f2dd24
|
||||
inlined_ast: f1d531bbe1b2e0bf0f30a1f7e86cce88c834fee9eb4d06548508907ad5f2dd24
|
||||
dce_ast: f1d531bbe1b2e0bf0f30a1f7e86cce88c834fee9eb4d06548508907ad5f2dd24
|
||||
bytecode: e8cc0536d26ff27b9fe9ff3ad45b575185b9f60c9d3910481ab66843af0f2171
|
||||
bytecode: 935fb69a9229d935e0f2ec6ce8774b279e8d2ab9496ef8dfcf061aec2088db31
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 81d3e2a9873213fa638e27f44b3b038c69bbe349c35b5356a772a7f68a485216
|
||||
inlined_ast: 81d3e2a9873213fa638e27f44b3b038c69bbe349c35b5356a772a7f68a485216
|
||||
dce_ast: da90f747cda7a8d74b4abbf06fb2220a0fb3420409befa188d8c812bffacee64
|
||||
bytecode: bf4397cd5bc3498d05f1d6582c3b4a868579aaa6b8f6f484f1c2ce9dd03a13a2
|
||||
bytecode: 649e93daf1fbf2a9870cd22788b26685b9f873b10ced0b6844974081b511080b
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 384e746fcbe1428be942f6ee12041562e0c1ae98b398c26da1d62fdb57181343
|
||||
inlined_ast: 384e746fcbe1428be942f6ee12041562e0c1ae98b398c26da1d62fdb57181343
|
||||
dce_ast: 384e746fcbe1428be942f6ee12041562e0c1ae98b398c26da1d62fdb57181343
|
||||
bytecode: 90662aea378f911f2798c1ece956f7a2566fd99d99a87d8285f1476edf468e43
|
||||
bytecode: b66977ddf8c6be2363f9c584853adf0dc546d28df9c4eb87ab94d393e9c39c59
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 7111dab311b76ad61366abb7a6e40586f44e17da7f8784eb6f8431dd0c41bd42
|
||||
inlined_ast: 7111dab311b76ad61366abb7a6e40586f44e17da7f8784eb6f8431dd0c41bd42
|
||||
dce_ast: 7111dab311b76ad61366abb7a6e40586f44e17da7f8784eb6f8431dd0c41bd42
|
||||
bytecode: 57bdcce5ea2ea7890a6a4786e4795f5c458da4b6b29f6295f86e15f11479f3e6
|
||||
bytecode: b9e119319f6a86cf6b4820d47924a35737646c2bee28ef72882d8e255cdaf7fb
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: c48dab53c83532533096307cda1460de12397de310e2b6622f644dcace4f4391
|
||||
inlined_ast: c48dab53c83532533096307cda1460de12397de310e2b6622f644dcace4f4391
|
||||
dce_ast: c5d03ece7d274dc56be11aa850f15744fa5a84399ed4d5fc7dfde1cf6af2268e
|
||||
bytecode: f6b06c8195fece8a8c55a0c4684f0135bbaadda789d192091b60afd9aa6c8874
|
||||
bytecode: bc2da8a1b63f9c24fb14b7468faa8cc14da40ce5c61c9a1c86804b808533b92a
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 29589d9c50c3654f9002ba09ee2354a4e073c7e6f7eb788df42ff77ea5f36a07
|
||||
inlined_ast: 29589d9c50c3654f9002ba09ee2354a4e073c7e6f7eb788df42ff77ea5f36a07
|
||||
dce_ast: 29589d9c50c3654f9002ba09ee2354a4e073c7e6f7eb788df42ff77ea5f36a07
|
||||
bytecode: b6438347d546b70daea75dda80a96df95c782793c3e40c92f1931903604c41bf
|
||||
bytecode: e31bed8381ccd85c771e3eba7b52867ed99d7cfbfadf9fed69211d5a815f89e2
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: bbf216c1e754d2012edb4ef4896499255d956bf4f39c0b9852ee45f75d914a0b
|
||||
inlined_ast: bbf216c1e754d2012edb4ef4896499255d956bf4f39c0b9852ee45f75d914a0b
|
||||
dce_ast: bbf216c1e754d2012edb4ef4896499255d956bf4f39c0b9852ee45f75d914a0b
|
||||
bytecode: ef0f05392652587de58875f041bb805a5a1172a153d96973638342d143798863
|
||||
bytecode: ad633a49970484d1285719af828974f068669c6aef5a1d0e6471cc1285469d09
|
||||
warnings: ""
|
||||
|
@ -8,4 +8,5 @@ outputs:
|
||||
flattened_ast: 60cf4f7e83d3ffc10b362b701749b0d5afcf8307e099bc5c7908c9ccb4df3efc
|
||||
inlined_ast: 60cf4f7e83d3ffc10b362b701749b0d5afcf8307e099bc5c7908c9ccb4df3efc
|
||||
dce_ast: 60cf4f7e83d3ffc10b362b701749b0d5afcf8307e099bc5c7908c9ccb4df3efc
|
||||
bytecode: b65dba415908458745a14bfc52abda70a0899732f807ba22f56776ab3fcbf589
|
||||
bytecode: 483aebac4ea170dd82b9056a667b2be13c0b9e0b957a151e5f833e0119f7650b
|
||||
warnings: ""
|
||||
|
@ -2,4 +2,4 @@
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- "Error [ETYC0372036]: Cannot use a `finalize` statement without a `finalize` block.\n --> compiler-test:5:9\n |\n 5 | return a + b then finalize(a, b);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372044]: Function must contain a `finalize` statement on all execution paths.\n --> compiler-test:8:5\n |\n 8 | function bar(a: u8, b: u8) -> u8 {\n 9 | return a + b;\n 10 | }\n | ^\nError [ETYC0372031]: Only transition functions can have a `finalize` block.\n --> compiler-test:12:5\n |\n 12 | finalize bar(a: u8, b: u8) -> u8 {\n 13 | return a + b;\n 14 | }\n | ^\n |\n = Remove the `finalize` block or use the keyword `transition` instead of `function`.\nError [ETYC0372031]: Only transition functions can have a `finalize` block.\n --> compiler-test:21:5\n |\n 21 | finalize mint_public(receiver: address, amount: u64) {\n 22 | increment(account, receiver, amount);\n 23 | }\n | ^\n |\n = Remove the `finalize` block or use the keyword `transition` instead of `function`.\nError [ETYC0372005]: Unknown variable `account`\n --> compiler-test:22:19\n |\n 22 | increment(account, receiver, amount);\n | ^^^^^^^\nError [ETYC0372004]: Could not determine the type of `account`\n --> compiler-test:22:19\n |\n 22 | increment(account, receiver, amount);\n | ^^^^^^^\n"
|
||||
- "Error [ETYC0372036]: Cannot use a `finalize` statement without a `finalize` block.\n --> compiler-test:5:9\n |\n 5 | return a + b then finalize(a, b);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372044]: Function must contain a `finalize` statement on all execution paths.\n --> compiler-test:8:5\n |\n 8 | function bar(a: u8, b: u8) -> u8 {\n 9 | return a + b;\n 10 | }\n | ^\nError [ETYC0372031]: Only transition functions can have a `finalize` block.\n --> compiler-test:12:5\n |\n 12 | finalize bar(a: u8, b: u8) -> u8 {\n 13 | return a + b;\n 14 | }\n | ^\n |\n = Remove the `finalize` block or use the keyword `transition` instead of `function`.\nError [ETYC0372071]: A finalize block cannot return a value.\n --> compiler-test:12:5\n |\n 12 | finalize bar(a: u8, b: u8) -> u8 {\n 13 | return a + b;\n 14 | }\n | ^\nError [ETYC0372031]: Only transition functions can have a `finalize` block.\n --> compiler-test:21:5\n |\n 21 | finalize mint_public(receiver: address, amount: u64) {\n 22 | Mapping::set(account, receiver, amount);\n 23 | }\n | ^\n |\n = Remove the `finalize` block or use the keyword `transition` instead of `function`.\nError [ETYC0372005]: Unknown variable `account`\n --> compiler-test:22:22\n |\n 22 | Mapping::set(account, receiver, amount);\n | ^^^^^^^\n"
|
||||
|
@ -1,11 +0,0 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
outputs:
|
||||
- - initial_ast: 6fa465e63f2b8e880d621cb1758b3d1c0edfa9ce09e6d4f0f28bbe6c2ca2b955
|
||||
unrolled_ast: 6fa465e63f2b8e880d621cb1758b3d1c0edfa9ce09e6d4f0f28bbe6c2ca2b955
|
||||
ssa_ast: 6fa465e63f2b8e880d621cb1758b3d1c0edfa9ce09e6d4f0f28bbe6c2ca2b955
|
||||
flattened_ast: 4b8969d1adf68074bc7a8458a9146e128041bf929f2f6a4e76a16ad2769b81b1
|
||||
inlined_ast: 4b8969d1adf68074bc7a8458a9146e128041bf929f2f6a4e76a16ad2769b81b1
|
||||
dce_ast: 4b8969d1adf68074bc7a8458a9146e128041bf929f2f6a4e76a16ad2769b81b1
|
||||
bytecode: 39aa8516297ece27331b633a72466d2ff0122d36beca663a48bc07589e2d3e15
|
5
tests/expectations/compiler/finalize/decrement_fail.out
Normal file
5
tests/expectations/compiler/finalize/decrement_fail.out
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- "Error [ETYC0372005]: Unknown function `decrement`\n --> compiler-test:11:9\n |\n 11 | decrement(amounts, addr, amount);\n | ^^^^^^^^^\nWarning [WPAR0370001]: The keyword `decrement` is deprecated.\n --> compiler-test:11:9\n |\n 11 | decrement(amounts, addr, amount);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n |\n = Use `Mapping::{get, get_or_init, set}` for manipulating on-chain mappings."
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
namespace: Compile
|
||||
expectation: Fail
|
||||
outputs:
|
||||
- "Error [ETYC0372007]: Expected one type from `Token`, but got `u128`\n --> compiler-test:18:33\n |\n 18 | decrement(tokens, addr, amount);\n | ^^^^^^\nError [ETYC0372007]: Expected one type from `address`, but got `u8`\n --> compiler-test:19:28\n |\n 19 | decrement(amounts, 1u8, amount);\n | ^^^\nError [ETYC0372007]: Expected one type from `u128`, but got `u8`\n --> compiler-test:20:34\n |\n 20 | decrement(amounts, addr, 1u8);\n | ^^^\nError [ETYC0372003]: Expected type `u64` but type `u8` was found\n --> compiler-test:21:61\n |\n 21 | decrement(tokens, addr, Token { owner: addr, gates: 1u8, amount: 1u8 });\n | ^^^\nError [ETYC0372003]: Expected type `u128` but type `u8` was found\n --> compiler-test:21:74\n |\n 21 | decrement(tokens, addr, Token { owner: addr, gates: 1u8, amount: 1u8 });\n | ^^^\nError [ETYC0372007]: Expected one type from `field, group, scalar, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128`, but got `Token`\n --> compiler-test:21:33\n |\n 21 | decrement(tokens, addr, Token { owner: addr, gates: 1u8, amount: 1u8 });\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372005]: Unknown variable `foo`\n --> compiler-test:22:19\n |\n 22 | decrement(foo, addr, amount);\n | ^^^\nError [ETYC0372004]: Could not determine the type of `foo`\n --> compiler-test:22:19\n |\n 22 | decrement(foo, addr, amount);\n | ^^^\n"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user