mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-30 23:33:27 +03:00
Merge pull request #1996 from AleoHQ/feat/codegen-for-function-calls
Codegen for Function Calls
This commit is contained in:
commit
7b739a35e1
@ -33,13 +33,13 @@ Contains the Circuit's name, as well as its members.
|
||||
The members are a function, or a variable, or a constant.
|
||||
For all of them the Circuit preserves their names.
|
||||
|
||||
#### [Decorators](./src/annotation.rs)
|
||||
#### [Annotations](./src/functions/annotation.rs)
|
||||
|
||||
An annotation node is a decorator that can be applied to a function.
|
||||
Stored on the function themselves despite being a top-level node.
|
||||
The node stores the name of the annotation, as well as any args passed to it.
|
||||
|
||||
#### [Functions](./src/functions/function.rs)
|
||||
#### [Functions](./src/functions/mod.rs)
|
||||
|
||||
A function node represents a defined function in a Leo Program.
|
||||
An order-preserving map of these are stored on the Program.
|
||||
|
@ -14,8 +14,27 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod function_input;
|
||||
pub use function_input::*;
|
||||
use crate::{simple_node_impl, Identifier, Node};
|
||||
|
||||
pub mod input_variable;
|
||||
pub use input_variable::*;
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// An annotation, e.g. @program.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Annotation {
|
||||
// TODO: Consider using a symbol instead of an identifier.
|
||||
/// The name of the annotation.
|
||||
pub identifier: Identifier,
|
||||
/// A span locating where the annotation occurred in the source.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
simple_node_impl!(Annotation);
|
||||
|
||||
impl fmt::Display for Annotation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "@{}", self.identifier)
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Block, FunctionInput, Identifier, Node, Type};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
|
||||
/// A function definition.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Function {
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
pub identifier: Identifier,
|
||||
/// The function's parameters.
|
||||
pub input: Vec<FunctionInput>,
|
||||
/// The function's required return type.
|
||||
pub output: Type,
|
||||
/// Any mapping to the core library.
|
||||
/// Always `None` when initially parsed.
|
||||
pub core_mapping: Cell<Option<Symbol>>,
|
||||
/// The body of the function.
|
||||
pub block: Block,
|
||||
/// The entire span of the function definition.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl PartialEq for Function {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.identifier == other.identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Function {}
|
||||
|
||||
impl Function {
|
||||
/// Returns function name.
|
||||
pub fn name(&self) -> Symbol {
|
||||
self.identifier.name
|
||||
}
|
||||
|
||||
/// Returns `true` if the function name is `main`.
|
||||
pub fn is_main(&self) -> bool {
|
||||
self.name() == sym::main
|
||||
}
|
||||
|
||||
///
|
||||
/// Private formatting method used for optimizing [fmt::Debug] and [fmt::Display] implementations.
|
||||
///
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "function {}", self.identifier)?;
|
||||
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
let returns = self.output.to_string();
|
||||
write!(f, "({}) -> {} {}", parameters, returns, self.block)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Function {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Function {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(Function);
|
@ -22,6 +22,7 @@ use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ParamMode {
|
||||
None,
|
||||
Const,
|
||||
Private,
|
||||
Public,
|
||||
@ -32,6 +33,7 @@ impl fmt::Display for ParamMode {
|
||||
use ParamMode::*;
|
||||
|
||||
match self {
|
||||
None => write!(f, ""),
|
||||
Const => write!(f, "const"),
|
||||
Private => write!(f, "private"),
|
||||
Public => write!(f, "public"),
|
||||
@ -41,7 +43,7 @@ impl fmt::Display for ParamMode {
|
||||
|
||||
/// A function parameter.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FunctionInputVariable {
|
||||
pub struct FunctionInput {
|
||||
/// The name the parameter is accessible as in the function's body.
|
||||
pub identifier: Identifier,
|
||||
/// The mode of the function parameter.
|
||||
@ -52,7 +54,7 @@ pub struct FunctionInputVariable {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl FunctionInputVariable {
|
||||
impl FunctionInput {
|
||||
pub fn new(identifier: Identifier, mode: ParamMode, type_: Type, span: Span) -> Self {
|
||||
Self {
|
||||
identifier,
|
||||
@ -67,7 +69,7 @@ impl FunctionInputVariable {
|
||||
}
|
||||
}
|
||||
|
||||
impl FunctionInputVariable {
|
||||
impl FunctionInput {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} ", self.mode)?;
|
||||
write!(f, "{}: ", self.identifier)?;
|
||||
@ -75,16 +77,16 @@ impl FunctionInputVariable {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FunctionInputVariable {
|
||||
impl fmt::Display for FunctionInput {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FunctionInputVariable {
|
||||
impl fmt::Debug for FunctionInput {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(FunctionInputVariable);
|
||||
crate::simple_node_impl!(FunctionInput);
|
@ -1,86 +0,0 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{FunctionInputVariable, Node};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Enumerates the possible inputs to a function.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub enum FunctionInput {
|
||||
/// A normal function parameter.
|
||||
Variable(FunctionInputVariable),
|
||||
}
|
||||
|
||||
impl FunctionInput {
|
||||
///
|
||||
/// Returns Option with FunctionInputVariable if the input is a variable.
|
||||
/// Returns None otherwise.
|
||||
///
|
||||
pub fn get_variable(&self) -> &FunctionInputVariable {
|
||||
match self {
|
||||
Self::Variable(var) => var,
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats the parameter to `f`.
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
FunctionInput::Variable(function_input) => write!(f, "{}", function_input),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FunctionInput {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FunctionInput {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for FunctionInput {
|
||||
/// Returns true if `self == other`. Does not compare spans.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(FunctionInput::Variable(left), FunctionInput::Variable(right)) => left.eq(right),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FunctionInput {}
|
||||
|
||||
impl Node for FunctionInput {
|
||||
fn span(&self) -> Span {
|
||||
use FunctionInput::*;
|
||||
match self {
|
||||
Variable(variable) => variable.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
use FunctionInput::*;
|
||||
match self {
|
||||
Variable(variable) => variable.span = span,
|
||||
}
|
||||
}
|
||||
}
|
@ -14,8 +14,80 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pub mod function;
|
||||
pub use function::*;
|
||||
pub mod annotation;
|
||||
pub use annotation::*;
|
||||
|
||||
pub mod input;
|
||||
pub use input::*;
|
||||
pub mod function_input;
|
||||
pub use function_input::*;
|
||||
|
||||
use crate::{Block, Identifier, Node, Type};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
|
||||
/// A function definition.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Function {
|
||||
/// Annotations on the function.
|
||||
pub annotations: Vec<Annotation>,
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
pub identifier: Identifier,
|
||||
/// The function's parameters.
|
||||
pub input: Vec<FunctionInput>,
|
||||
/// The function's required return type.
|
||||
pub output: Type,
|
||||
/// Any mapping to the core library.
|
||||
/// Always `None` when initially parsed.
|
||||
pub core_mapping: Cell<Option<Symbol>>,
|
||||
/// The body of the function.
|
||||
pub block: Block,
|
||||
/// The entire span of the function definition.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl PartialEq for Function {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.identifier == other.identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Function {}
|
||||
|
||||
impl Function {
|
||||
/// Returns function name.
|
||||
pub fn name(&self) -> Symbol {
|
||||
self.identifier.name
|
||||
}
|
||||
|
||||
/// Returns `true` if the function name is `main`.
|
||||
pub fn is_main(&self) -> bool {
|
||||
self.name() == sym::main
|
||||
}
|
||||
|
||||
///
|
||||
/// Private formatting method used for optimizing [fmt::Debug] and [fmt::Display] implementations.
|
||||
///
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "function {}", self.identifier)?;
|
||||
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
let returns = self.output.to_string();
|
||||
write!(f, "({}) -> {} {}", parameters, returns, self.block)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Function {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Function {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(Function);
|
||||
|
@ -280,6 +280,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
|
||||
|
||||
fn reconstruct_function(&mut self, input: Function) -> Function {
|
||||
Function {
|
||||
annotations: input.annotations,
|
||||
identifier: input.identifier,
|
||||
input: input.input,
|
||||
output: input.output,
|
||||
|
@ -30,6 +30,7 @@ impl ParserContext<'_> {
|
||||
let mut functions = IndexMap::new();
|
||||
let mut circuits = IndexMap::new();
|
||||
|
||||
// TODO: Condense logic
|
||||
while self.has_next() {
|
||||
match &self.token.token {
|
||||
Token::Import => {
|
||||
@ -40,6 +41,10 @@ impl ParserContext<'_> {
|
||||
let (id, circuit) = self.parse_circuit()?;
|
||||
circuits.insert(id, circuit);
|
||||
}
|
||||
Token::At => {
|
||||
let (id, function) = self.parse_function()?;
|
||||
functions.insert(id, function);
|
||||
}
|
||||
Token::Const if self.peek_is_function() => {
|
||||
let (id, function) = self.parse_function()?;
|
||||
functions.insert(id, function);
|
||||
@ -230,6 +235,7 @@ impl ParserContext<'_> {
|
||||
|
||||
/// Returns a [`ParamMode`] AST node if the next tokens represent a function parameter mode.
|
||||
pub(super) fn parse_function_parameter_mode(&mut self) -> Result<ParamMode> {
|
||||
// TODO: Allow explicit "private" mode.
|
||||
let public = self.eat(&Token::Public).then(|| self.prev_token.span);
|
||||
let constant = self.eat(&Token::Constant).then(|| self.prev_token.span);
|
||||
let const_ = self.eat(&Token::Const).then(|| self.prev_token.span);
|
||||
@ -241,7 +247,7 @@ impl ParserContext<'_> {
|
||||
match (public, constant, const_) {
|
||||
(None, Some(_), None) => Ok(ParamMode::Const),
|
||||
(None, None, Some(_)) => Ok(ParamMode::Const),
|
||||
(None, None, None) => Ok(ParamMode::Private),
|
||||
(None, None, None) => Ok(ParamMode::None),
|
||||
(Some(_), None, None) => Ok(ParamMode::Public),
|
||||
(Some(m1), Some(m2), None) | (Some(m1), None, Some(m2)) | (None, Some(m1), Some(m2)) => {
|
||||
Err(ParserError::inputs_multiple_variable_types_specified(m1 + m2).into())
|
||||
@ -256,9 +262,7 @@ impl ParserContext<'_> {
|
||||
fn parse_function_parameter(&mut self) -> Result<FunctionInput> {
|
||||
let mode = self.parse_function_parameter_mode()?;
|
||||
let (name, type_) = self.parse_typed_ident()?;
|
||||
Ok(FunctionInput::Variable(FunctionInputVariable::new(
|
||||
name, mode, type_, name.span,
|
||||
)))
|
||||
Ok(FunctionInput::new(name, mode, type_, name.span))
|
||||
}
|
||||
|
||||
/// Returns `true` if the next token is Function or if it is a Const followed by Function.
|
||||
@ -270,9 +274,31 @@ impl ParserContext<'_> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an [`Annotation`] AST node if the next tokens represent an annotation.
|
||||
fn parse_annotation(&mut self) -> Result<Annotation> {
|
||||
// Parse the `@` symbol and identifier.
|
||||
let start = self.expect(&Token::At)?;
|
||||
let identifier = self.expect_identifier()?;
|
||||
let span = start + identifier.span;
|
||||
|
||||
// TODO: Verify that this check is sound.
|
||||
// Check that there is no whitespace in between the `@` symbol and identifier.
|
||||
match identifier.span.hi.0 - start.lo.0 > 1 + identifier.name.to_string().len() as u32 {
|
||||
true => Err(ParserError::space_in_annotation(span).into()),
|
||||
false => Ok(Annotation { identifier, span }),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an [`(Identifier, Function)`] AST node if the next tokens represent a function name
|
||||
/// and function definition.
|
||||
fn parse_function(&mut self) -> Result<(Identifier, Function)> {
|
||||
// TODO: Handle dangling annotations.
|
||||
// TODO: Handle duplicate annotations.
|
||||
// Parse annotations, if they exist.
|
||||
let mut annotations = Vec::new();
|
||||
while self.look_ahead(0, |t| &t.token) == &Token::At {
|
||||
annotations.push(self.parse_annotation()?)
|
||||
}
|
||||
// Parse `function IDENT`.
|
||||
let start = self.expect(&Token::Function)?;
|
||||
let name = self.expect_identifier()?;
|
||||
@ -292,6 +318,7 @@ impl ParserContext<'_> {
|
||||
Ok((
|
||||
name,
|
||||
Function {
|
||||
annotations,
|
||||
identifier: name,
|
||||
input: inputs,
|
||||
output,
|
||||
|
@ -384,6 +384,7 @@ impl Token {
|
||||
)
|
||||
}
|
||||
'^' => return match_two(&mut input, Token::BitXor, '=', Token::BitXorAssign),
|
||||
'@' => return Ok((1, Token::At)),
|
||||
_ => (),
|
||||
}
|
||||
if let Some(identifier) = eat_identifier(&mut input) {
|
||||
|
@ -141,6 +141,7 @@ mod tests {
|
||||
}}
|
||||
||
|
||||
?
|
||||
@
|
||||
// test
|
||||
/* test */
|
||||
//"#;
|
||||
@ -153,7 +154,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
output,
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address bool const else false field for function group i128 i64 i32 i16 i8 if in input let mut return scalar string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> _ . .. / : ; < <= = == > >= [ ] { { } } || ? // test
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address bool const else false field for function group i128 i64 i32 i16 i8 if in input let mut return scalar string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
|
||||
/* test */ // "#
|
||||
);
|
||||
});
|
||||
|
@ -84,6 +84,7 @@ pub enum Token {
|
||||
Underscore,
|
||||
BitXor,
|
||||
BitXorAssign,
|
||||
At,
|
||||
|
||||
// Syntactic Grammar
|
||||
// Types
|
||||
@ -281,6 +282,7 @@ impl fmt::Display for Token {
|
||||
Underscore => write!(f, "_"),
|
||||
BitXor => write!(f, "^"),
|
||||
BitXorAssign => write!(f, "^="),
|
||||
At => write!(f, "@"),
|
||||
|
||||
Address => write!(f, "address"),
|
||||
Bool => write!(f, "bool"),
|
||||
|
@ -32,6 +32,9 @@ 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)>,
|
||||
/// Are we traversing a program function?
|
||||
/// A "program function" is a function that can be invoked by a user or another program.
|
||||
pub(crate) is_program_function: bool,
|
||||
}
|
||||
|
||||
impl<'a> CodeGenerator<'a> {
|
||||
@ -43,6 +46,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
current_function: None,
|
||||
variable_mapping: IndexMap::new(),
|
||||
composite_mapping: IndexMap::new(),
|
||||
is_program_function: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
}
|
||||
|
||||
fn visit_call(&mut self, input: &'a CallExpression) -> (String, String) {
|
||||
let mut call_instruction = format!(" {} ", input.function);
|
||||
let mut call_instruction = format!(" call {} ", input.function);
|
||||
let mut instructions = String::new();
|
||||
|
||||
for argument in input.arguments.iter() {
|
||||
|
@ -20,6 +20,7 @@ use leo_ast::{Circuit, CircuitMember, Function, Identifier, Program};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use itertools::Itertools;
|
||||
use leo_span::sym;
|
||||
use std::fmt::Write as _;
|
||||
|
||||
impl<'a> CodeGenerator<'a> {
|
||||
@ -60,14 +61,37 @@ impl<'a> CodeGenerator<'a> {
|
||||
// Newline separator.
|
||||
program_string.push('\n');
|
||||
|
||||
// Visit each `Function` in the Leo AST and produce a Aleo function instruction.
|
||||
program_string.push_str(
|
||||
&input
|
||||
.functions
|
||||
.values()
|
||||
.map(|function| self.visit_function(function))
|
||||
.join("\n"),
|
||||
);
|
||||
// Store closures and functions in separate strings.
|
||||
let mut closures = String::new();
|
||||
let mut functions = String::new();
|
||||
|
||||
// Visit each `Function` in the Leo AST and produce Aleo instructions.
|
||||
input.functions.values().for_each(|function| {
|
||||
// If the function is annotated with `@program`, then it is a program function.
|
||||
for annotation in function.annotations.iter() {
|
||||
if annotation.identifier.name == sym::program {
|
||||
self.is_program_function = true;
|
||||
}
|
||||
}
|
||||
|
||||
let function_string = self.visit_function(function);
|
||||
|
||||
if self.is_program_function {
|
||||
functions.push_str(&function_string);
|
||||
functions.push('\n');
|
||||
} else {
|
||||
closures.push_str(&function_string);
|
||||
closures.push('\n');
|
||||
}
|
||||
|
||||
// Unset the `is_program_function` flag.
|
||||
self.is_program_function = false;
|
||||
});
|
||||
|
||||
// Closures must precede functions in the Aleo program.
|
||||
program_string.push_str(&closures);
|
||||
program_string.push('\n');
|
||||
program_string.push_str(&functions);
|
||||
|
||||
program_string
|
||||
}
|
||||
@ -140,7 +164,11 @@ impl<'a> CodeGenerator<'a> {
|
||||
self.current_function = Some(function);
|
||||
|
||||
// Construct the header of the function.
|
||||
let mut function_string = format!("function {}:\n", function.identifier);
|
||||
// If a function is a program function, generate an Aleo `function`, otherwise generate an Aleo `closure`.
|
||||
let mut function_string = match self.is_program_function {
|
||||
true => format!("function {}:\n", function.identifier),
|
||||
false => format!("closure {}:\n", function.identifier),
|
||||
};
|
||||
|
||||
// Construct and append the input declarations of the function.
|
||||
for input in function.input.iter() {
|
||||
@ -148,10 +176,9 @@ impl<'a> CodeGenerator<'a> {
|
||||
self.next_register += 1;
|
||||
|
||||
self.variable_mapping
|
||||
.insert(&input.get_variable().identifier.name, register_string.clone());
|
||||
.insert(&input.identifier.name, register_string.clone());
|
||||
|
||||
let type_string =
|
||||
self.visit_type_with_visibility(&input.get_variable().type_, Some(input.get_variable().mode()));
|
||||
let type_string = self.visit_type_with_visibility(&input.type_, input.mode());
|
||||
writeln!(function_string, " input {} as {};", register_string, type_string,)
|
||||
.expect("failed to write to string");
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use crate::CodeGenerator;
|
||||
|
||||
use leo_ast::{
|
||||
AssignStatement, Block, ConditionalStatement, ConsoleStatement, DefinitionStatement, Expression,
|
||||
IterationStatement, ReturnStatement, Statement,
|
||||
IterationStatement, ParamMode, ReturnStatement, Statement,
|
||||
};
|
||||
|
||||
use itertools::Itertools;
|
||||
@ -38,8 +38,8 @@ impl<'a> CodeGenerator<'a> {
|
||||
|
||||
fn visit_return(&mut self, input: &'a ReturnStatement) -> String {
|
||||
let (operand, mut expression_instructions) = self.visit_expression(&input.expression);
|
||||
let types = self.visit_return_type(&self.current_function.unwrap().output, None);
|
||||
// TODO: Bytecode functions have an associated output mode. Currently defaulting to private since we do not yet support this at the Leo level.
|
||||
let types = self.visit_return_type(&self.current_function.unwrap().output, ParamMode::Private);
|
||||
let mut instructions = operand
|
||||
.split('\n')
|
||||
.into_iter()
|
||||
|
@ -52,22 +52,29 @@ impl<'a> CodeGenerator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn visit_type_with_visibility(&mut self, input: &'a Type, visibility: Option<ParamMode>) -> String {
|
||||
pub(crate) fn visit_type_with_visibility(&mut self, input: &'a Type, visibility: ParamMode) -> String {
|
||||
let mut type_string = self.visit_type(input);
|
||||
|
||||
if let Type::Identifier(_) = input {
|
||||
// Do not append anything for record and circuit types.
|
||||
} else {
|
||||
// Append `.private` to return type.
|
||||
// todo: CAUTION private by default.
|
||||
write!(type_string, ".{}", visibility.unwrap_or(ParamMode::Private)).expect("failed to write to string");
|
||||
// Only program functions need a visibility associated with the input type.
|
||||
if self.is_program_function {
|
||||
// If a visibility is not provided in a program function, then it is private by default.
|
||||
let visibility = match visibility {
|
||||
ParamMode::None => ParamMode::Private,
|
||||
_ => visibility,
|
||||
};
|
||||
write!(type_string, ".{}", visibility).expect("failed to write to string");
|
||||
}
|
||||
}
|
||||
|
||||
type_string
|
||||
}
|
||||
|
||||
/// Returns one or more types equal to the number of return tuple members.
|
||||
pub(crate) fn visit_return_type(&mut self, input: &'a Type, visibility: Option<ParamMode>) -> Vec<String> {
|
||||
pub(crate) fn visit_return_type(&mut self, input: &'a Type, visibility: ParamMode) -> Vec<String> {
|
||||
// Handle return tuples.
|
||||
if let Type::Tuple(types) = input {
|
||||
types
|
||||
|
@ -34,6 +34,7 @@ impl ProgramReconstructor for Unroller<'_> {
|
||||
|
||||
// Reconstruct the function block.
|
||||
let reconstructed_function = Function {
|
||||
annotations: function.annotations,
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
|
@ -18,8 +18,8 @@ use crate::StaticSingleAssigner;
|
||||
use itertools::Itertools;
|
||||
|
||||
use leo_ast::{
|
||||
Expression, Function, FunctionInput, ProgramReconstructor, ReturnStatement, Statement, StatementReconstructor,
|
||||
TernaryExpression, TupleExpression,
|
||||
Expression, Function, ProgramReconstructor, ReturnStatement, Statement, StatementReconstructor, TernaryExpression,
|
||||
TupleExpression,
|
||||
};
|
||||
|
||||
impl ProgramReconstructor for StaticSingleAssigner<'_> {
|
||||
@ -30,15 +30,9 @@ impl ProgramReconstructor for StaticSingleAssigner<'_> {
|
||||
|
||||
// There is no need to reconstruct `function.inputs`.
|
||||
// However, for each input, we must add each symbol to the rename table.
|
||||
for input in function.input.iter() {
|
||||
match input {
|
||||
FunctionInput::Variable(function_input_variable) => {
|
||||
self.rename_table.update(
|
||||
function_input_variable.identifier.name,
|
||||
function_input_variable.identifier.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
for input_variable in function.input.iter() {
|
||||
self.rename_table
|
||||
.update(input_variable.identifier.name, input_variable.identifier.name);
|
||||
}
|
||||
|
||||
let mut block = self.reconstruct_block(function.block);
|
||||
@ -98,6 +92,7 @@ impl ProgramReconstructor for StaticSingleAssigner<'_> {
|
||||
self.pop();
|
||||
|
||||
Function {
|
||||
annotations: function.annotations,
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
|
@ -552,7 +552,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
.iter()
|
||||
.zip(input.arguments.iter())
|
||||
.for_each(|(expected, argument)| {
|
||||
self.visit_expression(argument, &Some(expected.get_variable().type_.clone()));
|
||||
self.visit_expression(argument, &Some(expected.type_.clone()));
|
||||
});
|
||||
|
||||
Some(ret)
|
||||
|
@ -26,6 +26,15 @@ use std::collections::HashSet;
|
||||
|
||||
impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
fn visit_function(&mut self, input: &'a Function) {
|
||||
// Check that the function's annotations are valid.
|
||||
for annotation in input.annotations.iter() {
|
||||
match annotation.identifier.name {
|
||||
// Set `is_program_function` to true if the corresponding annotation is found.
|
||||
sym::program => self.is_program_function = true,
|
||||
_ => self.emit_err(TypeCheckerError::unknown_annotation(annotation, annotation.span)),
|
||||
}
|
||||
}
|
||||
|
||||
let prev_st = std::mem::take(&mut self.symbol_table);
|
||||
self.symbol_table
|
||||
.swap(prev_st.borrow().lookup_fn_scope(input.name()).unwrap());
|
||||
@ -33,10 +42,16 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
|
||||
self.has_return = false;
|
||||
self.parent = Some(input.name());
|
||||
input.input.iter().for_each(|i| {
|
||||
let input_var = i.get_variable();
|
||||
input.input.iter().for_each(|input_var| {
|
||||
self.assert_not_tuple(input_var.span, &input_var.type_);
|
||||
|
||||
// If the function is not a program function, then check that the parameters do not have an associated mode.
|
||||
if !self.is_program_function && input_var.mode() != ParamMode::None {
|
||||
self.emit_err(TypeCheckerError::helper_function_inputs_cannot_have_modes(
|
||||
input_var.span,
|
||||
));
|
||||
}
|
||||
|
||||
// Check for conflicting variable names.
|
||||
if let Err(err) = self.symbol_table.borrow_mut().insert_variable(
|
||||
input_var.identifier.name,
|
||||
@ -65,6 +80,9 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
|
||||
let prev_st = *self.symbol_table.borrow_mut().parent.take().unwrap();
|
||||
self.symbol_table.swap(prev_st.lookup_fn_scope(input.name()).unwrap());
|
||||
self.symbol_table = RefCell::new(prev_st);
|
||||
|
||||
// Unset `is_program_function` flag.
|
||||
self.is_program_function = false;
|
||||
}
|
||||
|
||||
fn visit_circuit(&mut self, input: &'a Circuit) {
|
||||
|
@ -30,6 +30,9 @@ pub struct TypeChecker<'a> {
|
||||
pub(crate) parent: Option<Symbol>,
|
||||
pub(crate) has_return: bool,
|
||||
pub(crate) negate: bool,
|
||||
/// Are we traversing a program function?
|
||||
/// A "program function" is a function that can be invoked by a user or another program.
|
||||
pub(crate) is_program_function: bool,
|
||||
}
|
||||
|
||||
const BOOLEAN_TYPE: Type = Type::Boolean;
|
||||
@ -63,6 +66,7 @@ impl<'a> TypeChecker<'a> {
|
||||
/// Returns a new type checker given a symbol table and error handler.
|
||||
pub fn new(symbol_table: SymbolTable, handler: &'a Handler) -> Self {
|
||||
Self {
|
||||
is_program_function: false,
|
||||
symbol_table: RefCell::new(symbol_table),
|
||||
handler,
|
||||
parent: None,
|
||||
|
@ -216,6 +216,7 @@ symbols! {
|
||||
owner,
|
||||
gates,
|
||||
_nonce,
|
||||
program,
|
||||
|
||||
// input file
|
||||
registers,
|
||||
|
@ -253,4 +253,11 @@ create_messages!(
|
||||
msg: format!("Invalid import call to non-leo file `{name}`."),
|
||||
help: Some("Only imports of Leo `.leo` files are currently supported.".to_string()),
|
||||
}
|
||||
|
||||
@formatted
|
||||
space_in_annotation {
|
||||
args: (),
|
||||
msg: "Illegal spacing in the annotation declaration.",
|
||||
help: Some("Remove whitespace between the `@` symbol and the identifier.".to_string()),
|
||||
}
|
||||
);
|
||||
|
@ -273,4 +273,19 @@ create_messages!(
|
||||
msg: format!("Loop body contains a return statement or always returns."),
|
||||
help: Some("Remove the code in the loop body that always returns.".to_string()),
|
||||
}
|
||||
|
||||
// TODO: Consider emitting a warning instead of an error.
|
||||
@formatted
|
||||
unknown_annotation {
|
||||
args: (annotation: impl Display),
|
||||
msg: format!("Unknown annotation: `{annotation}`."),
|
||||
help: Some("Use a valid annotation. The Leo compiler supports: `@program`".to_string()),
|
||||
}
|
||||
|
||||
@formatted
|
||||
helper_function_inputs_cannot_have_modes {
|
||||
args: (),
|
||||
msg: format!("Helper functions cannot have modes associated with their inputs."),
|
||||
help: Some("Consider removing the mode or adding a `@program` annotation to the function.".to_string()),
|
||||
}
|
||||
);
|
||||
|
@ -16,6 +16,7 @@
|
||||
// Note that the implementation below uses tuples instead of arrays.
|
||||
// The implementation also manually unrolls the loop.
|
||||
|
||||
@program
|
||||
function bubble_sort(
|
||||
arr0: u32,
|
||||
arr1: u32,
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Core circuit functions are built-in to the Leo language and call handwritten, optimized circuits in the AVM.
|
||||
// To call a core circuit function, use the correct capitalized circuit identifier followed by two colons
|
||||
// and then the function. Example: `Pedersen64::hash()`.
|
||||
@program
|
||||
function main(a: field) -> field {
|
||||
let b: field = BHP256::hash(a);
|
||||
let c: field = Poseidon2::hash(b);
|
||||
|
@ -1,5 +1,7 @@
|
||||
// This function takes a group coordinate as input `a` and performs several operations which should output the `0group`.
|
||||
// Note that the operations can be called as associated functions on the `a` variable.
|
||||
|
||||
@program
|
||||
function main(a: group) -> group {
|
||||
// unary
|
||||
let e: group = a.double(); // 2a
|
||||
|
@ -1,8 +0,0 @@
|
||||
circuit Foo {
|
||||
x: u64,
|
||||
y: u64,
|
||||
}
|
||||
|
||||
function bar(x: u64, y: u64) -> Foo {
|
||||
return Foo {x, y};
|
||||
}
|
@ -2,6 +2,3 @@
|
||||
[main]
|
||||
public a: u32 = 1u32;
|
||||
b: u32 = 2u32; // Input variable `b` is private by default.
|
||||
|
||||
[foo]
|
||||
x: u64 = 5u64;
|
@ -1,7 +1,5 @@
|
||||
import foo.leo;
|
||||
|
||||
// The 'helloworld' main function.
|
||||
|
||||
@program
|
||||
function main(public a: u32, b: u32) -> u32 {
|
||||
return a + b;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
import point.leo;
|
||||
|
||||
// The main function.
|
||||
@program
|
||||
function main(public a: u32, b: u32) -> u32 {
|
||||
return a + b;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ circuit Message {
|
||||
|
||||
// The "main" function of this Leo program takes a "Message" circuit type as input.
|
||||
// To see how to input variable "m" is passed in open up `inputs/message.in`.
|
||||
@program
|
||||
function main(m: Message) -> field {
|
||||
|
||||
// 1. Define the "Message" type.
|
||||
|
@ -1,3 +1,6 @@
|
||||
// This example demonstrates an example of a minting and transferring a token in Leo.
|
||||
|
||||
// The `Token` record datatype.
|
||||
record Token {
|
||||
// The token owner.
|
||||
owner: address,
|
||||
@ -9,6 +12,7 @@ record Token {
|
||||
|
||||
// The `mint` function initializes a new record with the
|
||||
// to the receiver of tokens in `r1` for the receiver in `r0`.
|
||||
@program
|
||||
function mint(owner: address, amount: u64) -> Token {
|
||||
return Token {
|
||||
owner: owner,
|
||||
@ -19,6 +23,7 @@ function mint(owner: address, amount: u64) -> Token {
|
||||
|
||||
// The `transfer` function sends the specified number of tokens
|
||||
// to the receiver from the provided token record.
|
||||
@program
|
||||
function transfer(token: Token, to: address, amount: u64) -> (Token, Token) {
|
||||
|
||||
// Checks the given token record has sufficient balance.
|
||||
|
@ -69,6 +69,7 @@ impl MainFile {
|
||||
fn template(&self) -> String {
|
||||
format!(
|
||||
r#"// The '{}' main function.
|
||||
@program
|
||||
function main(public a: u32, b: u32) -> u32 {{
|
||||
let c: u32 = a + b;
|
||||
return c;
|
||||
|
@ -3,6 +3,7 @@ namespace: Bench
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
@program
|
||||
function hAgrPJzARlhWKDGNpe () -> i128 {
|
||||
const NtoD9dCOP8: bool = false;
|
||||
if 60367u16 < 59376u16 && 291621465261548374864687596926221274642u128 <= 158647603833518715931164380862541000072u128 - 92087114510286551502623665863269979099u128 - 6505284705764791705801152244952567434u128 + 141283471013642106073249086828215491558u128 / 178739495978647499334333189200118397544u128 * 0u128 / 69358574294733597814948265413698301968u128 || 32532971286371518024146524900992744351u128 / 73930302096579937058701857000560614114u128 * 0u128 + 219449183973603283961254860147322285177u128 > 72259425234692696526333349807208361947u128 || 94519913150306783765596349821018468848i128 == -145523637561949662187440225436346186585i128 {
|
||||
@ -158,6 +159,7 @@ function hAgrPJzARlhWKDGNpe () -> i128 {
|
||||
return ILtBGr5IWbok66cGZo;
|
||||
}
|
||||
|
||||
@program
|
||||
function kIebmldut (
|
||||
constant dS71uQ: i64,
|
||||
constant Dj87fM: i8,
|
||||
@ -181,6 +183,7 @@ function kIebmldut (
|
||||
return dS71uQ;
|
||||
}
|
||||
|
||||
@program
|
||||
function zfUb (n1uGb8qYUbxVeMc: u8) -> field {
|
||||
const KGVaawVj_y8MuU: u32 = 3924454878u32;
|
||||
let Rdg5wrR4uJy2GqrYJL: u64 = 11167188615068932487u64;
|
||||
@ -228,6 +231,7 @@ function zfUb (n1uGb8qYUbxVeMc: u8) -> field {
|
||||
return WIRhzmLSHlgn;
|
||||
}
|
||||
|
||||
@program
|
||||
function ey1Y83xwKF4m (
|
||||
constant WQQo: i64,
|
||||
constant JzJ3bWUp5V5umYC8mLb: u16
|
||||
@ -9118,6 +9122,7 @@ function ey1Y83xwKF4m (
|
||||
}
|
||||
}
|
||||
|
||||
@program
|
||||
function WNIRQ5XU (
|
||||
Sao22ploN2: u16,
|
||||
UAiLILX: u16,
|
||||
@ -13276,6 +13281,7 @@ function WNIRQ5XU (
|
||||
}
|
||||
}
|
||||
|
||||
@program
|
||||
function yKAI11uAlhAC0MKuVaQH (
|
||||
constant m3q_thgJckCDtZw5: bool,
|
||||
constant dtIzYvZXAHLLq10L: u16,
|
||||
@ -13310,6 +13316,7 @@ function yKAI11uAlhAC0MKuVaQH (
|
||||
return mO8ojODfy3e;
|
||||
}
|
||||
|
||||
@program
|
||||
function EFXa_yV (
|
||||
constant lKpXyYB: i16,
|
||||
vekEtDz_FKl4w: field,
|
||||
@ -15001,6 +15008,7 @@ function EFXa_yV (
|
||||
}
|
||||
}
|
||||
|
||||
@program
|
||||
function nxMY18LG (
|
||||
constant rv4FX2AtXtt: i128,
|
||||
constant MyEqz3: u128,
|
||||
@ -29496,6 +29504,7 @@ function nxMY18LG (
|
||||
}
|
||||
}
|
||||
|
||||
@program
|
||||
function ujkWfQ5r_1Yi (
|
||||
XcnTSn5: bool,
|
||||
UIgsv89hNR83neLpzYD: i128,
|
||||
@ -29530,6 +29539,7 @@ function ujkWfQ5r_1Yi (
|
||||
return iVzW;
|
||||
}
|
||||
|
||||
@program
|
||||
function mRhFZzGYWFW3 () -> u16 {
|
||||
let It967SlNwbUzoY3v4iTL: u8 = 217u8;
|
||||
It967SlNwbUzoY3v4iTL = It967SlNwbUzoY3v4iTL;
|
||||
@ -29603,6 +29613,7 @@ function mRhFZzGYWFW3 () -> u16 {
|
||||
return ooC9znSzVmwewD2KL;
|
||||
}
|
||||
|
||||
@program
|
||||
function ys4SGkFTY8T8t (
|
||||
constant VdZ1o3oai2nDE8: field,
|
||||
constant fCskhvo4Zl155ClaZ: u64,
|
||||
@ -29623,6 +29634,7 @@ function ys4SGkFTY8T8t (
|
||||
return fCskhvo4Zl155ClaZ;
|
||||
}
|
||||
|
||||
@program
|
||||
function h0Eadw (
|
||||
constant IkNFf7x4G3: u32,
|
||||
sygZ: u128,
|
||||
@ -34176,6 +34188,7 @@ function h0Eadw (
|
||||
return sygZ;
|
||||
}
|
||||
|
||||
@program
|
||||
function dz88xZBpyG7y9Q9yZS (
|
||||
constant QDWdZ1P6Uxy: u8,
|
||||
TxLtm4JHFtIxvMQqdXp: i64,
|
||||
@ -35481,6 +35494,7 @@ function dz88xZBpyG7y9Q9yZS (
|
||||
}
|
||||
}
|
||||
|
||||
@program
|
||||
function WAqDjVpXCNT8mVu () -> u64 {
|
||||
const g96iIWKOcZyNfysxQae: u16 = 45302u16;
|
||||
let uayEuyji0EjFEjvUSFY: i128 = hAgrPJzARlhWKDGNpe();
|
||||
@ -35622,6 +35636,7 @@ function WAqDjVpXCNT8mVu () -> u64 {
|
||||
return IbtV5ITueWPb6mx9PG;
|
||||
}
|
||||
|
||||
@program
|
||||
function ed_5yepk9ZH7ESz4EfU (
|
||||
c7iEW8nfI4pcpTUIkmn: field,
|
||||
m9g1DEE853bNFWWvV: u32,
|
||||
@ -44516,6 +44531,7 @@ function ed_5yepk9ZH7ESz4EfU (
|
||||
}
|
||||
}
|
||||
|
||||
@program
|
||||
function main (constant QZe9: i128) -> i64 {
|
||||
if 18788u16 != 61211u16 && 33352u16 >= ujkWfQ5r_1Yi(false, QZe9, 14152i16, QZe9) {
|
||||
let MYnKyRAZnaEo0Ngls7: u128 = 196095035652207868244240086789795221266u128;
|
||||
|
@ -3,6 +3,7 @@ namespace: Bench
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
@program
|
||||
function main() -> u32 {
|
||||
const a = 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32;
|
||||
const b = 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32 + 1u32;
|
||||
|
@ -3,199 +3,392 @@ namespace: Bench
|
||||
expectation: Pass
|
||||
*/
|
||||
|
||||
@program
|
||||
function main() -> u8 {
|
||||
return x191(0u32);
|
||||
}
|
||||
|
||||
@program
|
||||
function x0(val: u8) -> u8 { return val; }
|
||||
@program
|
||||
function x1(val: u8) -> u8 { return x0(val); }
|
||||
@program
|
||||
function x2(val: u8) -> u8 { return x1(val); }
|
||||
@program
|
||||
function x3(val: u8) -> u8 { return x2(val); }
|
||||
@program
|
||||
function x4(val: u8) -> u8 { return x3(val); }
|
||||
@program
|
||||
function x5(val: u8) -> u8 { return x4(val); }
|
||||
@program
|
||||
function x6(val: u8) -> u8 { return x5(val); }
|
||||
@program
|
||||
function x7(val: u8) -> u8 { return x6(val); }
|
||||
@program
|
||||
function x8(val: u8) -> u8 { return x7(val); }
|
||||
@program
|
||||
function x9(val: u8) -> u8 { return x8(val); }
|
||||
@program
|
||||
function x10(val: u8) -> u8 { return x9(val); }
|
||||
@program
|
||||
function x11(val: u8) -> u8 { return x10(val); }
|
||||
@program
|
||||
function x12(val: u8) -> u8 { return x11(val); }
|
||||
@program
|
||||
function x13(val: u8) -> u8 { return x12(val); }
|
||||
@program
|
||||
function x14(val: u8) -> u8 { return x13(val); }
|
||||
@program
|
||||
function x15(val: u8) -> u8 { return x14(val); }
|
||||
@program
|
||||
function x16(val: u8) -> u8 { return x15(val); }
|
||||
@program
|
||||
function x17(val: u8) -> u8 { return x16(val); }
|
||||
@program
|
||||
function x18(val: u8) -> u8 { return x17(val); }
|
||||
@program
|
||||
function x19(val: u8) -> u8 { return x18(val); }
|
||||
@program
|
||||
function x20(val: u8) -> u8 { return x19(val); }
|
||||
@program
|
||||
function x21(val: u8) -> u8 { return x20(val); }
|
||||
@program
|
||||
function x22(val: u8) -> u8 { return x21(val); }
|
||||
@program
|
||||
function x23(val: u8) -> u8 { return x22(val); }
|
||||
@program
|
||||
function x24(val: u8) -> u8 { return x23(val); }
|
||||
@program
|
||||
function x25(val: u8) -> u8 { return x24(val); }
|
||||
@program
|
||||
function x26(val: u8) -> u8 { return x25(val); }
|
||||
@program
|
||||
function x27(val: u8) -> u8 { return x26(val); }
|
||||
@program
|
||||
function x28(val: u8) -> u8 { return x27(val); }
|
||||
@program
|
||||
function x29(val: u8) -> u8 { return x28(val); }
|
||||
@program
|
||||
function x30(val: u8) -> u8 { return x29(val); }
|
||||
@program
|
||||
function x31(val: u8) -> u8 { return x30(val); }
|
||||
@program
|
||||
function x32(val: u8) -> u8 { return x31(val); }
|
||||
@program
|
||||
function x33(val: u8) -> u8 { return x32(val); }
|
||||
@program
|
||||
function x34(val: u8) -> u8 { return x33(val); }
|
||||
@program
|
||||
function x35(val: u8) -> u8 { return x34(val); }
|
||||
@program
|
||||
function x36(val: u8) -> u8 { return x35(val); }
|
||||
@program
|
||||
function x37(val: u8) -> u8 { return x36(val); }
|
||||
@program
|
||||
function x38(val: u8) -> u8 { return x37(val); }
|
||||
@program
|
||||
function x39(val: u8) -> u8 { return x38(val); }
|
||||
@program
|
||||
function x40(val: u8) -> u8 { return x39(val); }
|
||||
@program
|
||||
function x41(val: u8) -> u8 { return x40(val); }
|
||||
@program
|
||||
function x42(val: u8) -> u8 { return x41(val); }
|
||||
@program
|
||||
function x43(val: u8) -> u8 { return x42(val); }
|
||||
@program
|
||||
function x44(val: u8) -> u8 { return x43(val); }
|
||||
@program
|
||||
function x45(val: u8) -> u8 { return x44(val); }
|
||||
@program
|
||||
function x46(val: u8) -> u8 { return x45(val); }
|
||||
@program
|
||||
function x47(val: u8) -> u8 { return x46(val); }
|
||||
@program
|
||||
function x48(val: u8) -> u8 { return x47(val); }
|
||||
@program
|
||||
function x49(val: u8) -> u8 { return x48(val); }
|
||||
@program
|
||||
function x50(val: u8) -> u8 { return x49(val); }
|
||||
@program
|
||||
function x51(val: u8) -> u8 { return x50(val); }
|
||||
@program
|
||||
function x52(val: u8) -> u8 { return x51(val); }
|
||||
@program
|
||||
function x53(val: u8) -> u8 { return x52(val); }
|
||||
@program
|
||||
function x54(val: u8) -> u8 { return x53(val); }
|
||||
@program
|
||||
function x55(val: u8) -> u8 { return x54(val); }
|
||||
@program
|
||||
function x56(val: u8) -> u8 { return x55(val); }
|
||||
@program
|
||||
function x57(val: u8) -> u8 { return x56(val); }
|
||||
@program
|
||||
function x58(val: u8) -> u8 { return x57(val); }
|
||||
@program
|
||||
function x59(val: u8) -> u8 { return x58(val); }
|
||||
@program
|
||||
function x60(val: u8) -> u8 { return x59(val); }
|
||||
@program
|
||||
function x61(val: u8) -> u8 { return x60(val); }
|
||||
@program
|
||||
function x62(val: u8) -> u8 { return x61(val); }
|
||||
@program
|
||||
function x63(val: u8) -> u8 { return x62(val); }
|
||||
@program
|
||||
function x64(val: u8) -> u8 { return x63(val); }
|
||||
@program
|
||||
function x65(val: u8) -> u8 { return x64(val); }
|
||||
@program
|
||||
function x66(val: u8) -> u8 { return x65(val); }
|
||||
@program
|
||||
function x67(val: u8) -> u8 { return x66(val); }
|
||||
@program
|
||||
function x68(val: u8) -> u8 { return x67(val); }
|
||||
@program
|
||||
function x69(val: u8) -> u8 { return x68(val); }
|
||||
@program
|
||||
function x70(val: u8) -> u8 { return x69(val); }
|
||||
@program
|
||||
function x71(val: u8) -> u8 { return x70(val); }
|
||||
@program
|
||||
function x72(val: u8) -> u8 { return x71(val); }
|
||||
@program
|
||||
function x73(val: u8) -> u8 { return x72(val); }
|
||||
@program
|
||||
function x74(val: u8) -> u8 { return x73(val); }
|
||||
@program
|
||||
function x75(val: u8) -> u8 { return x74(val); }
|
||||
@program
|
||||
function x76(val: u8) -> u8 { return x75(val); }
|
||||
@program
|
||||
function x77(val: u8) -> u8 { return x76(val); }
|
||||
@program
|
||||
function x78(val: u8) -> u8 { return x77(val); }
|
||||
@program
|
||||
function x79(val: u8) -> u8 { return x78(val); }
|
||||
@program
|
||||
function x80(val: u8) -> u8 { return x79(val); }
|
||||
@program
|
||||
function x81(val: u8) -> u8 { return x80(val); }
|
||||
@program
|
||||
function x82(val: u8) -> u8 { return x81(val); }
|
||||
@program
|
||||
function x83(val: u8) -> u8 { return x82(val); }
|
||||
@program
|
||||
function x84(val: u8) -> u8 { return x83(val); }
|
||||
@program
|
||||
function x85(val: u8) -> u8 { return x84(val); }
|
||||
@program
|
||||
function x86(val: u8) -> u8 { return x85(val); }
|
||||
@program
|
||||
function x87(val: u8) -> u8 { return x86(val); }
|
||||
@program
|
||||
function x88(val: u8) -> u8 { return x87(val); }
|
||||
@program
|
||||
function x89(val: u8) -> u8 { return x88(val); }
|
||||
@program
|
||||
function x90(val: u8) -> u8 { return x89(val); }
|
||||
@program
|
||||
function x91(val: u8) -> u8 { return x90(val); }
|
||||
@program
|
||||
function x92(val: u8) -> u8 { return x91(val); }
|
||||
@program
|
||||
function x93(val: u8) -> u8 { return x92(val); }
|
||||
@program
|
||||
function x94(val: u8) -> u8 { return x93(val); }
|
||||
@program
|
||||
function x95(val: u8) -> u8 { return x94(val); }
|
||||
@program
|
||||
function x96(val: u8) -> u8 { return x95(val); }
|
||||
@program
|
||||
function x97(val: u8) -> u8 { return x96(val); }
|
||||
@program
|
||||
function x98(val: u8) -> u8 { return x97(val); }
|
||||
@program
|
||||
function x99(val: u8) -> u8 { return x98(val); }
|
||||
@program
|
||||
function x100(val: u8) -> u8 { return x99(val); }
|
||||
@program
|
||||
function x101(val: u8) -> u8 { return x100(val); }
|
||||
@program
|
||||
function x102(val: u8) -> u8 { return x101(val); }
|
||||
@program
|
||||
function x103(val: u8) -> u8 { return x102(val); }
|
||||
@program
|
||||
function x104(val: u8) -> u8 { return x103(val); }
|
||||
@program
|
||||
function x105(val: u8) -> u8 { return x104(val); }
|
||||
@program
|
||||
function x106(val: u8) -> u8 { return x105(val); }
|
||||
@program
|
||||
function x107(val: u8) -> u8 { return x106(val); }
|
||||
@program
|
||||
function x108(val: u8) -> u8 { return x107(val); }
|
||||
@program
|
||||
function x109(val: u8) -> u8 { return x108(val); }
|
||||
@program
|
||||
function x110(val: u8) -> u8 { return x109(val); }
|
||||
@program
|
||||
function x111(val: u8) -> u8 { return x110(val); }
|
||||
@program
|
||||
function x112(val: u8) -> u8 { return x111(val); }
|
||||
@program
|
||||
function x113(val: u8) -> u8 { return x112(val); }
|
||||
@program
|
||||
function x114(val: u8) -> u8 { return x113(val); }
|
||||
@program
|
||||
function x115(val: u8) -> u8 { return x114(val); }
|
||||
@program
|
||||
function x116(val: u8) -> u8 { return x115(val); }
|
||||
@program
|
||||
function x117(val: u8) -> u8 { return x116(val); }
|
||||
@program
|
||||
function x118(val: u8) -> u8 { return x117(val); }
|
||||
@program
|
||||
function x119(val: u8) -> u8 { return x118(val); }
|
||||
@program
|
||||
function x120(val: u8) -> u8 { return x119(val); }
|
||||
@program
|
||||
function x121(val: u8) -> u8 { return x120(val); }
|
||||
@program
|
||||
function x122(val: u8) -> u8 { return x121(val); }
|
||||
@program
|
||||
function x123(val: u8) -> u8 { return x122(val); }
|
||||
@program
|
||||
function x124(val: u8) -> u8 { return x123(val); }
|
||||
@program
|
||||
function x125(val: u8) -> u8 { return x124(val); }
|
||||
@program
|
||||
function x126(val: u8) -> u8 { return x125(val); }
|
||||
@program
|
||||
function x127(val: u8) -> u8 { return x126(val); }
|
||||
@program
|
||||
function x128(val: u8) -> u8 { return x127(val); }
|
||||
@program
|
||||
function x129(val: u8) -> u8 { return x128(val); }
|
||||
@program
|
||||
function x130(val: u8) -> u8 { return x129(val); }
|
||||
@program
|
||||
function x131(val: u8) -> u8 { return x130(val); }
|
||||
@program
|
||||
function x132(val: u8) -> u8 { return x131(val); }
|
||||
@program
|
||||
function x133(val: u8) -> u8 { return x132(val); }
|
||||
@program
|
||||
function x134(val: u8) -> u8 { return x133(val); }
|
||||
@program
|
||||
function x135(val: u8) -> u8 { return x134(val); }
|
||||
@program
|
||||
function x136(val: u8) -> u8 { return x135(val); }
|
||||
@program
|
||||
function x137(val: u8) -> u8 { return x136(val); }
|
||||
@program
|
||||
function x138(val: u8) -> u8 { return x137(val); }
|
||||
@program
|
||||
function x139(val: u8) -> u8 { return x138(val); }
|
||||
@program
|
||||
function x140(val: u8) -> u8 { return x139(val); }
|
||||
@program
|
||||
function x141(val: u8) -> u8 { return x140(val); }
|
||||
@program
|
||||
function x142(val: u8) -> u8 { return x141(val); }
|
||||
@program
|
||||
function x143(val: u8) -> u8 { return x142(val); }
|
||||
@program
|
||||
function x144(val: u8) -> u8 { return x143(val); }
|
||||
@program
|
||||
function x145(val: u8) -> u8 { return x144(val); }
|
||||
@program
|
||||
function x146(val: u8) -> u8 { return x145(val); }
|
||||
@program
|
||||
function x147(val: u8) -> u8 { return x146(val); }
|
||||
@program
|
||||
function x148(val: u8) -> u8 { return x147(val); }
|
||||
@program
|
||||
function x149(val: u8) -> u8 { return x148(val); }
|
||||
@program
|
||||
function x150(val: u8) -> u8 { return x149(val); }
|
||||
@program
|
||||
function x151(val: u8) -> u8 { return x150(val); }
|
||||
@program
|
||||
function x152(val: u8) -> u8 { return x151(val); }
|
||||
@program
|
||||
function x153(val: u8) -> u8 { return x152(val); }
|
||||
@program
|
||||
function x154(val: u8) -> u8 { return x153(val); }
|
||||
@program
|
||||
function x155(val: u8) -> u8 { return x154(val); }
|
||||
@program
|
||||
function x156(val: u8) -> u8 { return x155(val); }
|
||||
@program
|
||||
function x157(val: u8) -> u8 { return x156(val); }
|
||||
@program
|
||||
function x158(val: u8) -> u8 { return x157(val); }
|
||||
@program
|
||||
function x159(val: u8) -> u8 { return x158(val); }
|
||||
@program
|
||||
function x160(val: u8) -> u8 { return x159(val); }
|
||||
@program
|
||||
function x161(val: u8) -> u8 { return x160(val); }
|
||||
@program
|
||||
function x162(val: u8) -> u8 { return x161(val); }
|
||||
@program
|
||||
function x163(val: u8) -> u8 { return x162(val); }
|
||||
@program
|
||||
function x164(val: u8) -> u8 { return x163(val); }
|
||||
@program
|
||||
function x165(val: u8) -> u8 { return x164(val); }
|
||||
@program
|
||||
function x166(val: u8) -> u8 { return x165(val); }
|
||||
@program
|
||||
function x167(val: u8) -> u8 { return x166(val); }
|
||||
@program
|
||||
function x168(val: u8) -> u8 { return x167(val); }
|
||||
@program
|
||||
function x169(val: u8) -> u8 { return x168(val); }
|
||||
@program
|
||||
function x170(val: u8) -> u8 { return x169(val); }
|
||||
@program
|
||||
function x171(val: u8) -> u8 { return x170(val); }
|
||||
@program
|
||||
function x172(val: u8) -> u8 { return x171(val); }
|
||||
@program
|
||||
function x173(val: u8) -> u8 { return x172(val); }
|
||||
@program
|
||||
function x174(val: u8) -> u8 { return x173(val); }
|
||||
@program
|
||||
function x175(val: u8) -> u8 { return x174(val); }
|
||||
@program
|
||||
function x176(val: u8) -> u8 { return x175(val); }
|
||||
@program
|
||||
function x177(val: u8) -> u8 { return x176(val); }
|
||||
@program
|
||||
function x178(val: u8) -> u8 { return x177(val); }
|
||||
@program
|
||||
function x179(val: u8) -> u8 { return x178(val); }
|
||||
@program
|
||||
function x180(val: u8) -> u8 { return x179(val); }
|
||||
@program
|
||||
function x181(val: u8) -> u8 { return x180(val); }
|
||||
@program
|
||||
function x182(val: u8) -> u8 { return x181(val); }
|
||||
@program
|
||||
function x183(val: u8) -> u8 { return x182(val); }
|
||||
@program
|
||||
function x184(val: u8) -> u8 { return x183(val); }
|
||||
@program
|
||||
function x185(val: u8) -> u8 { return x184(val); }
|
||||
@program
|
||||
function x186(val: u8) -> u8 { return x185(val); }
|
||||
@program
|
||||
function x187(val: u8) -> u8 { return x186(val); }
|
||||
@program
|
||||
function x188(val: u8) -> u8 { return x187(val); }
|
||||
@program
|
||||
function x189(val: u8) -> u8 { return x188(val); }
|
||||
@program
|
||||
function x190(val: u8) -> u8 { return x189(val); }
|
||||
@program
|
||||
function x191(val: u8) -> u8 { return x190(val); }
|
||||
|
@ -5,6 +5,7 @@ input_file: inputs/address1.in
|
||||
*/
|
||||
|
||||
|
||||
@program
|
||||
function main (x: address) -> bool {
|
||||
let a: address = aleo1fj982yqchhy973kz7e9jk6er7t6qd6jm9anplnlprem507w6lv9spwvfxx;
|
||||
let b: bool = x.eq(a);
|
||||
|
@ -5,6 +5,7 @@ input_file: inputs/branch.in
|
||||
*/
|
||||
|
||||
|
||||
@program
|
||||
function main (x: address, y: bool) -> bool {
|
||||
let z: address = aleo1fj982yqchhy973kz7e9jk6er7t6qd6jm9anplnlprem507w6lv9spwvfxx;
|
||||
if y {
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/address1.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(x: address) -> bool {
|
||||
const sender: address = aleo10qerras5799u6k7rjtc9y3hcwxuykr45qra7x7dp6jgnc0923czqm0lgta;
|
||||
|
||||
|
@ -6,6 +6,7 @@ input_file:
|
||||
- inputs/address2.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(x: address) -> bool {
|
||||
const sender: address = aleo1l7ytv5jqjzpxtjqttl5z9mle8ujcpac9t6tkge5f4haah4pxas8sagzecd;
|
||||
const receiver: address = aleo1dtpkpg3d653mdlzh6g028937qdgujecn5gw5tzh7ftcvyz7jxvfqw6t8p6;
|
||||
|
@ -8,6 +8,7 @@ input_file:
|
||||
- inputs/true_true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool, b: bool) -> bool {
|
||||
return a && b;
|
||||
}
|
@ -8,6 +8,7 @@ input_file:
|
||||
- inputs/true_true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool, b: bool) -> bool {
|
||||
return a ? b : false;
|
||||
}
|
@ -8,6 +8,7 @@ input_file:
|
||||
- inputs/true_true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool, b: bool) -> bool {
|
||||
return a == b;
|
||||
}
|
@ -8,6 +8,7 @@ input_file:
|
||||
- inputs/true_true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool, b: bool) -> bool {
|
||||
return a != b;
|
||||
}
|
@ -8,6 +8,7 @@ input_file:
|
||||
- inputs/true_true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool, b: bool) -> bool {
|
||||
// unary
|
||||
let h: bool = a.not();
|
||||
|
@ -8,6 +8,7 @@ input_file:
|
||||
- inputs/true_true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool, b: bool) -> bool {
|
||||
return a || b;
|
||||
}
|
@ -14,6 +14,7 @@ circuit Foo {
|
||||
x: u32
|
||||
}
|
||||
|
||||
@program
|
||||
function main(x: u32) -> u32 {
|
||||
let a: Foo = Foo { x: x };
|
||||
return a.x;
|
||||
|
@ -8,6 +8,7 @@ circuit Foo {
|
||||
x: u32,
|
||||
}
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
const a: Foo = Foo { x: 1u32 };
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/true.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool) -> bool {
|
||||
console.assert(a == true);
|
||||
return a == true;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
console.error("hello error");
|
||||
return y == true;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
console.log("hello world");
|
||||
return y == true;
|
||||
|
@ -7,6 +7,7 @@ input_file:
|
||||
*/
|
||||
|
||||
// Conditionally add two u32 integers and log the result to the console.
|
||||
@program
|
||||
function main(a: u32, b: u32) -> bool {
|
||||
if a == b {
|
||||
console.log("{}=={}", a, b); // This line should not fail.
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
console.log("a = {}", y);
|
||||
return y == true;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
console.log("{}", 1u32);
|
||||
return y == true;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
console.log("{} {}", 1u32, true);
|
||||
return y == true;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/int64.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(
|
||||
i8_value: i8,
|
||||
i16_value: i16,
|
||||
|
@ -7,6 +7,7 @@ input_file: inputs/dummy.in
|
||||
// @test
|
||||
// function fake_test() {}
|
||||
|
||||
@program
|
||||
function main(y: bool) -> bool {
|
||||
return y == true;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field, c: field) -> bool {
|
||||
return a + b == c;
|
||||
}
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field, c: field) -> bool {
|
||||
return a / b != c;
|
||||
}
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a == b;
|
||||
}
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field) -> bool {
|
||||
const negOneField: field = -1field;
|
||||
return negOneField + a == 0field;
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field, c: field) -> bool {
|
||||
return a * b == c;
|
||||
}
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field) -> bool {
|
||||
return -a == -b;
|
||||
}
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field) -> bool {
|
||||
// unary
|
||||
let f: field = a.inv();
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field) -> bool {
|
||||
const negOneField: field = -1field;
|
||||
return negOneField ** 2field == 1field;
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field, c: field) -> bool {
|
||||
return a - b == c;
|
||||
}
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/fields.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: field, b: field, c: field) -> bool {
|
||||
return b == 1field ? a == 1field : c == 2field;
|
||||
}
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/integers.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: u32) -> u32 {
|
||||
if a == 2u32 {
|
||||
return 3u32;
|
||||
|
22
tests/compiler/function/function_call.leo
Normal file
22
tests/compiler/function/function_call.leo
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
namespace: Compile
|
||||
expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: u32, b: u32, y: bool) -> u32 {
|
||||
if y {
|
||||
return adder(a, b);
|
||||
} else {
|
||||
return subber(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
function adder(a: u32, b: u32) -> u32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
function subber(a: u32, b: u32) -> u32 {
|
||||
return a - b;
|
||||
}
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/three.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group, c: group) -> bool {
|
||||
console.assert(a + b == c);
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/eq.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group) -> bool {
|
||||
console.assert(a == b);
|
||||
return a == b;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/eq.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group) -> bool {
|
||||
console.assert(a == b);
|
||||
return a == b;
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar, b: group, c: scalar) -> bool {
|
||||
let d: group = 1817767092074430972953743941103352519057913259183777531581123188265134806220group * a;
|
||||
let e: group = a * 1817767092074430972953743941103352519057913259183777531581123188265134806220group;
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/dummy.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group) -> bool {
|
||||
console.assert(a == b);
|
||||
return a == b;
|
||||
|
@ -5,6 +5,7 @@ input_file:
|
||||
- inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar, b: group) -> group {
|
||||
return a * b;
|
||||
}
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/point.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group) -> group {
|
||||
return 1scalar * a;
|
||||
}
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/eq.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group) -> bool {
|
||||
console.assert(-a == b);
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/three.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group) -> bool {
|
||||
// unary
|
||||
let e: group = a.double();
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/point.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group) -> bool {
|
||||
return a == (0, 1)group;
|
||||
}
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/three.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group, c: group) -> bool {
|
||||
console.assert(a - b == c);
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/point.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: group, b: group, c: group) -> bool {
|
||||
const r: group = true ? a : b;
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar) -> group {
|
||||
let b: group = (0, 1)group;
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar) -> group {
|
||||
let b: group = (0, +)group;
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar) -> group {
|
||||
let b: group = (0, _)group;
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar) -> group {
|
||||
let b: group = (0, -)group;
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/scalar_group.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: scalar) -> group {
|
||||
let element: group = 0group;
|
||||
|
||||
|
@ -4,6 +4,7 @@ expectation: Pass
|
||||
input_file: inputs/main.in
|
||||
*/
|
||||
|
||||
@program
|
||||
function main(a: bool) -> bool {
|
||||
return a == true;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user