Merge pull request #2348 from AleoHQ/testnet3.3

[Feature] Upgrades for Phase 3.
This commit is contained in:
d0cd 2023-04-18 19:05:07 -07:00 committed by GitHub
commit 80005d67e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
504 changed files with 2881 additions and 2838 deletions

620
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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,
}

View 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,
}
}
}

View File

@ -17,6 +17,9 @@
pub mod annotation;
pub use annotation::*;
pub mod core_function;
pub use core_function::*;
pub mod variant;
pub use variant::*;

View File

@ -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::*;

View File

@ -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;

View File

@ -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 {

View File

@ -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());

View File

@ -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);

View File

@ -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);

View File

@ -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),
}

View File

@ -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"

View File

@ -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);

View File

@ -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);

View 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");
}

View File

@ -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()
}

View File

@ -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"

View File

@ -1,596 +0,0 @@
GNU General Public License
==========================
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. &lt;<https://fsf.org/>&gt;
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
&lt;<http://www.gnu.org/licenses/>&gt;.
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
&lt;<http://www.gnu.org/philosophy/why-not-lgpl.html>&gt;.

View File

@ -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)

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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::*;

View File

@ -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());
}

View File

@ -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.

View File

@ -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)?;

View File

@ -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)
}

View File

@ -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,

View File

@ -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"),

View File

@ -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"

View File

@ -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,
}

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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), _) => {

View File

@ -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) {

View File

@ -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.");

View File

@ -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,
}))
}

View File

@ -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);

View File

@ -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
}

View File

@ -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()));
}

View File

@ -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()));
}
}
});

View File

@ -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);

View File

@ -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,
}
}
}

View File

@ -147,12 +147,16 @@ symbols! {
BHP768,
BHP1024,
commit,
get,
get_or_init,
hash,
Mapping,
Pedersen64,
Pedersen128,
Poseidon2,
Poseidon4,
Poseidon8,
set,
// types
address,

View File

@ -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,
}

View File

@ -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()),
}
);

View File

@ -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,
}
);

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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),
}
}

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 5b0842e447b4e1f92f4bcd22824ed5e12c51c8db145d1541763d10ad3dc1f37a
inlined_ast: 5b0842e447b4e1f92f4bcd22824ed5e12c51c8db145d1541763d10ad3dc1f37a
dce_ast: 946b0fe81e942060d870c228afb1a31c42501fb8f9c481d35d7908b226af5cbe
bytecode: 31bab7a79a7dfdfbcd4a7a3f26cd813b48d7c1438dec3fd4905a81845161dba1
bytecode: e434c09cee27a5dfb5a4e9e9fd26aa2ba6e7f0653fad3a4f2a7d85983ba559c9
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: c1b6954bff1ce18c0bb3be1cd6392a554a15989c90939c99e375221b1003e3b7
inlined_ast: c1b6954bff1ce18c0bb3be1cd6392a554a15989c90939c99e375221b1003e3b7
dce_ast: c1b6954bff1ce18c0bb3be1cd6392a554a15989c90939c99e375221b1003e3b7
bytecode: b192f4b7f52da46a22cec3aec7e8c14b6e3fad7c40b9d0c0990255902fb596ef
bytecode: da1b0a83a17b801368b0a583b158d88d9d807a33000c8e89e82da123c8041aea
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: f9458e7824444415aa9f3feec4924461f49dee915429e63dec244806d3812722
inlined_ast: f9458e7824444415aa9f3feec4924461f49dee915429e63dec244806d3812722
dce_ast: f9458e7824444415aa9f3feec4924461f49dee915429e63dec244806d3812722
bytecode: 4903abf35d22e4264aae4bf26b908108d11d981d069c247793cea817dd8851a7
bytecode: bde2653fac0393940c5400272e53492228206e50abb36ce080b95043003ee976
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 1041763865cf86407bf30dae2b003ec9094e91e79c3e5b493b54fbd67cdd8f24
inlined_ast: 1041763865cf86407bf30dae2b003ec9094e91e79c3e5b493b54fbd67cdd8f24
dce_ast: 1041763865cf86407bf30dae2b003ec9094e91e79c3e5b493b54fbd67cdd8f24
bytecode: 5cbdf4a6a290f80540d2653153c57495eaf45432bc7ce44d52af2b5d0594951c
bytecode: c0b90b7f7e80041dc1a314c1a87290534936018fb001c6e1291266a02393c6f2
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 4e7759584ade51a19ff90284e5ee1ac91af6dad5cd966568b708ead553a8a4bd
inlined_ast: 4e7759584ade51a19ff90284e5ee1ac91af6dad5cd966568b708ead553a8a4bd
dce_ast: 4e7759584ade51a19ff90284e5ee1ac91af6dad5cd966568b708ead553a8a4bd
bytecode: e3deaf24a91bcb77628f7af29d4ad6d0ba67215617d6cfe753168543123ce7d2
bytecode: 134904b86b96581876c2ca0c6ead651dda0dc9f2fb6dc583400133410b7deede
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: de891bab08a157399fdceeeccc7c3d4fd70cc3f75d1ca694a4fcd0344fdaac20
inlined_ast: de891bab08a157399fdceeeccc7c3d4fd70cc3f75d1ca694a4fcd0344fdaac20
dce_ast: de891bab08a157399fdceeeccc7c3d4fd70cc3f75d1ca694a4fcd0344fdaac20
bytecode: d0d3f79c32e6cb17c98afa2f1d4861d0f71d7f805a87712b3491ef0a9e1b4892
bytecode: 56a9fa48a00d1b38b6f60a93ef2168b2c0ce9c23ba3cb7bffa40debfc1b16180
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: b39344c70e1a23869b236146ace198addf0801b348deedfb3e4ff1e3c4ace904
inlined_ast: b39344c70e1a23869b236146ace198addf0801b348deedfb3e4ff1e3c4ace904
dce_ast: b39344c70e1a23869b236146ace198addf0801b348deedfb3e4ff1e3c4ace904
bytecode: e742ac3b95a8971f2018963aba6d915ea53205c21443d0b11ad52a42ad443b97
bytecode: 2332d5b7ed9910dc65c885e1aeedbbde00e02d95a55caa300a9cb72456707034
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 84fd34b95b75f6d72b28164a9cb2ac80fa4149564c8c187b0ead1e14d2299a63
inlined_ast: 84fd34b95b75f6d72b28164a9cb2ac80fa4149564c8c187b0ead1e14d2299a63
dce_ast: 84fd34b95b75f6d72b28164a9cb2ac80fa4149564c8c187b0ead1e14d2299a63
bytecode: 1db874ad15d9bb70df7372ed3250cc6d0f65992e17788cd90c656ef1e1ceb63e
bytecode: 990eee0b87d70df046bad969201ad8afabff10162eb70c00f837fde81fed4104
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 1e61c9d9ccdae7fb4aed4d7332538438839bef08a322f52fabcf46eac7bfc9c8
inlined_ast: 1e61c9d9ccdae7fb4aed4d7332538438839bef08a322f52fabcf46eac7bfc9c8
dce_ast: ab80f3a28ba9de58b165074c3ffae7e5be48e721bf17219252cecc0a6fb8b6e4
bytecode: fedea8c873d237103657ba0902968bf5be3e854c95b2720b28fda529c5b87ff1
bytecode: bb260232bbd0ccede368961a31abeef5edc7e00cab3348b4b8518d4e5798a6b5
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: cf5034c292702654bd282c10c8d1abafed8ed328f8e6cd0a01b286438809afd5
inlined_ast: cf5034c292702654bd282c10c8d1abafed8ed328f8e6cd0a01b286438809afd5
dce_ast: cf5034c292702654bd282c10c8d1abafed8ed328f8e6cd0a01b286438809afd5
bytecode: e859520fd52dbdf69b14a3c3d9bad64bf6165084fb949912224eda3ccab9b638
bytecode: c3a0c03f4324a6dd6baea42e664ffad91868714739e03525dcbc968582007ceb
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 7a2b73a748d86babab5ca7a4f9e513cfd028dcbadc7df8baeb7774ffb54c1b43
inlined_ast: 7a2b73a748d86babab5ca7a4f9e513cfd028dcbadc7df8baeb7774ffb54c1b43
dce_ast: 7a2b73a748d86babab5ca7a4f9e513cfd028dcbadc7df8baeb7774ffb54c1b43
bytecode: fdc5659b97d4dbfea710ca848dcffa29bcd4da3a7a54739fb916e5292284a1a4
bytecode: 2d96971b7ff11cd865ed1b79ca417d062b970f3442cf9e6f53f033b5f258c556
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 083a9af2e592de0c827b15230cd2307daae4b90e324e35714f474d50cbb59162
inlined_ast: 083a9af2e592de0c827b15230cd2307daae4b90e324e35714f474d50cbb59162
dce_ast: 083a9af2e592de0c827b15230cd2307daae4b90e324e35714f474d50cbb59162
bytecode: 9006475518263541b3a855db6907377b638ef28f2a44caf4e26db7991c3b58ef
bytecode: 3ff716b96c532801f4fa5310f4eedf8f96fe15bd7db3bf087e7b64a161153945
warnings: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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"

View File

@ -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: ""

View File

@ -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: ""

View File

@ -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: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: bc4a52e6fb7998c2a8a454306e75598177546db8f32a5a79e95ead68abc72880
inlined_ast: bc4a52e6fb7998c2a8a454306e75598177546db8f32a5a79e95ead68abc72880
dce_ast: bc4a52e6fb7998c2a8a454306e75598177546db8f32a5a79e95ead68abc72880
bytecode: 9a1e5bb7b8d932d4afd347a856bfb38db144771f49a0d9589ef14236338e3dcf
bytecode: 651a250bda995df00cf3b4659d1ea35912ed94da32b5d487677dead9126b5d69
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 9c98dfcdcb403983efb0b1078246ca9e3c3e8fe913f6ceabbd9a87b63f3fc3a4
inlined_ast: 9c98dfcdcb403983efb0b1078246ca9e3c3e8fe913f6ceabbd9a87b63f3fc3a4
dce_ast: 9c98dfcdcb403983efb0b1078246ca9e3c3e8fe913f6ceabbd9a87b63f3fc3a4
bytecode: 230d4f2bda3933eb4fafc4dda4ce0087e74e4cbd9c65349746da561cbb3f99da
bytecode: 587770d63e2d2fe866f99683df9a32da50b718ee3a92aec0d9491cbb8569b80d
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 0840cf638ec3532c7702d10bbbfcf2fbfc8c8f7c54e532acb4ac46cbb7c8ed61
inlined_ast: 0840cf638ec3532c7702d10bbbfcf2fbfc8c8f7c54e532acb4ac46cbb7c8ed61
dce_ast: 0840cf638ec3532c7702d10bbbfcf2fbfc8c8f7c54e532acb4ac46cbb7c8ed61
bytecode: fa960590c979aea4bdfe07b7d37060bb593f73f745974241e2db578bd7ba2ced
bytecode: 8076383080c6f141d8c6038360d4c9494a44f39b20f85614faf57bb7f6e3a10d
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: f1d531bbe1b2e0bf0f30a1f7e86cce88c834fee9eb4d06548508907ad5f2dd24
inlined_ast: f1d531bbe1b2e0bf0f30a1f7e86cce88c834fee9eb4d06548508907ad5f2dd24
dce_ast: f1d531bbe1b2e0bf0f30a1f7e86cce88c834fee9eb4d06548508907ad5f2dd24
bytecode: e8cc0536d26ff27b9fe9ff3ad45b575185b9f60c9d3910481ab66843af0f2171
bytecode: 935fb69a9229d935e0f2ec6ce8774b279e8d2ab9496ef8dfcf061aec2088db31
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 81d3e2a9873213fa638e27f44b3b038c69bbe349c35b5356a772a7f68a485216
inlined_ast: 81d3e2a9873213fa638e27f44b3b038c69bbe349c35b5356a772a7f68a485216
dce_ast: da90f747cda7a8d74b4abbf06fb2220a0fb3420409befa188d8c812bffacee64
bytecode: bf4397cd5bc3498d05f1d6582c3b4a868579aaa6b8f6f484f1c2ce9dd03a13a2
bytecode: 649e93daf1fbf2a9870cd22788b26685b9f873b10ced0b6844974081b511080b
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 384e746fcbe1428be942f6ee12041562e0c1ae98b398c26da1d62fdb57181343
inlined_ast: 384e746fcbe1428be942f6ee12041562e0c1ae98b398c26da1d62fdb57181343
dce_ast: 384e746fcbe1428be942f6ee12041562e0c1ae98b398c26da1d62fdb57181343
bytecode: 90662aea378f911f2798c1ece956f7a2566fd99d99a87d8285f1476edf468e43
bytecode: b66977ddf8c6be2363f9c584853adf0dc546d28df9c4eb87ab94d393e9c39c59
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 7111dab311b76ad61366abb7a6e40586f44e17da7f8784eb6f8431dd0c41bd42
inlined_ast: 7111dab311b76ad61366abb7a6e40586f44e17da7f8784eb6f8431dd0c41bd42
dce_ast: 7111dab311b76ad61366abb7a6e40586f44e17da7f8784eb6f8431dd0c41bd42
bytecode: 57bdcce5ea2ea7890a6a4786e4795f5c458da4b6b29f6295f86e15f11479f3e6
bytecode: b9e119319f6a86cf6b4820d47924a35737646c2bee28ef72882d8e255cdaf7fb
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: c48dab53c83532533096307cda1460de12397de310e2b6622f644dcace4f4391
inlined_ast: c48dab53c83532533096307cda1460de12397de310e2b6622f644dcace4f4391
dce_ast: c5d03ece7d274dc56be11aa850f15744fa5a84399ed4d5fc7dfde1cf6af2268e
bytecode: f6b06c8195fece8a8c55a0c4684f0135bbaadda789d192091b60afd9aa6c8874
bytecode: bc2da8a1b63f9c24fb14b7468faa8cc14da40ce5c61c9a1c86804b808533b92a
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 29589d9c50c3654f9002ba09ee2354a4e073c7e6f7eb788df42ff77ea5f36a07
inlined_ast: 29589d9c50c3654f9002ba09ee2354a4e073c7e6f7eb788df42ff77ea5f36a07
dce_ast: 29589d9c50c3654f9002ba09ee2354a4e073c7e6f7eb788df42ff77ea5f36a07
bytecode: b6438347d546b70daea75dda80a96df95c782793c3e40c92f1931903604c41bf
bytecode: e31bed8381ccd85c771e3eba7b52867ed99d7cfbfadf9fed69211d5a815f89e2
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: bbf216c1e754d2012edb4ef4896499255d956bf4f39c0b9852ee45f75d914a0b
inlined_ast: bbf216c1e754d2012edb4ef4896499255d956bf4f39c0b9852ee45f75d914a0b
dce_ast: bbf216c1e754d2012edb4ef4896499255d956bf4f39c0b9852ee45f75d914a0b
bytecode: ef0f05392652587de58875f041bb805a5a1172a153d96973638342d143798863
bytecode: ad633a49970484d1285719af828974f068669c6aef5a1d0e6471cc1285469d09
warnings: ""

View File

@ -8,4 +8,5 @@ outputs:
flattened_ast: 60cf4f7e83d3ffc10b362b701749b0d5afcf8307e099bc5c7908c9ccb4df3efc
inlined_ast: 60cf4f7e83d3ffc10b362b701749b0d5afcf8307e099bc5c7908c9ccb4df3efc
dce_ast: 60cf4f7e83d3ffc10b362b701749b0d5afcf8307e099bc5c7908c9ccb4df3efc
bytecode: b65dba415908458745a14bfc52abda70a0899732f807ba22f56776ab3fcbf589
bytecode: 483aebac4ea170dd82b9056a667b2be13c0b9e0b957a151e5f833e0119f7650b
warnings: ""

View File

@ -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"

View File

@ -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

View 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."

View File

@ -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