Merge branch 'master' into leo-manifest-dependencies

This commit is contained in:
damirka 2021-08-02 18:51:01 +03:00
commit 7d2ba89cae
57 changed files with 528 additions and 257 deletions

View File

@ -1 +1 @@
v1.5.2
v1.5.3

28
Cargo.lock generated
View File

@ -1159,7 +1159,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "leo-abnf"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"abnf",
"anyhow",
@ -1167,7 +1167,7 @@ dependencies = [
[[package]]
name = "leo-asg"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"criterion",
"indexmap",
@ -1183,14 +1183,14 @@ dependencies = [
[[package]]
name = "leo-asg-passes"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"leo-asg",
]
[[package]]
name = "leo-ast"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"anyhow",
"criterion",
@ -1205,7 +1205,7 @@ dependencies = [
[[package]]
name = "leo-compiler"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"bincode",
"hex",
@ -1243,7 +1243,7 @@ dependencies = [
[[package]]
name = "leo-imports"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"indexmap",
"leo-asg",
@ -1255,7 +1255,7 @@ dependencies = [
[[package]]
name = "leo-input"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"from-pest",
"pest",
@ -1267,7 +1267,7 @@ dependencies = [
[[package]]
name = "leo-lang"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"ansi_term 0.12.1",
"anyhow",
@ -1311,11 +1311,11 @@ dependencies = [
[[package]]
name = "leo-linter"
version = "1.5.2"
version = "1.5.3"
[[package]]
name = "leo-package"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"indexmap",
"lazy_static",
@ -1329,7 +1329,7 @@ dependencies = [
[[package]]
name = "leo-parser"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"criterion",
"indexmap",
@ -1346,7 +1346,7 @@ dependencies = [
[[package]]
name = "leo-state"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"indexmap",
"leo-ast",
@ -1363,7 +1363,7 @@ dependencies = [
[[package]]
name = "leo-synthesizer"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"hex",
"num-bigint",
@ -1378,7 +1378,7 @@ dependencies = [
[[package]]
name = "leo-test-framework"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"serde",
"serde_json",

View File

@ -1,6 +1,6 @@
[package]
name = "leo-lang"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "The Leo programming language"
homepage = "https://aleo.org"
@ -43,35 +43,35 @@ members = [
[dependencies.leo-ast]
path = "./ast"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-compiler]
path = "./compiler"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-imports]
path = "./imports"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-input]
path = "./input"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-package]
path = "./package"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-parser]
path = "./parser"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-state]
path = "./state"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-synthesizer]
path = "./synthesizer"
version = "1.5.2"
version = "1.5.3"
[dependencies.snarkvm-algorithms]
version = "0.7.4"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-asg-passes"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "The Leo programming language"
homepage = "https://aleo.org"
@ -22,4 +22,4 @@ path = "src/lib.rs"
[dependencies.leo-asg]
path = "../asg"
version = "1.5.2"
version = "1.5.3"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-asg"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "ASG of the Leo programming language"
homepage = "https://aleo.org"
@ -30,11 +30,11 @@ version = "1.7"
version = "1.0"
[dependencies.leo-ast]
version = "1.5.2"
version = "1.5.3"
path = "../ast"
[dependencies.leo-parser]
version = "1.5.2"
version = "1.5.3"
path = "../parser"
[dependencies.num-bigint]

View File

@ -238,9 +238,7 @@ impl<'a, T: Monoid, R: MonoidalReducerStatement<'a, T>> MonoidalDirector<'a, T,
pub fn reduce_console(&mut self, input: &ConsoleStatement<'a>) -> T {
let argument = match &input.function {
ConsoleFunction::Assert(e) => self.reduce_expression(e.get()),
ConsoleFunction::Debug(f) | ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => {
self.reduce_formatted_string(f)
}
ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => self.reduce_formatted_string(f),
};
self.reducer.reduce_console(input, argument)

View File

@ -259,7 +259,7 @@ impl<'a, R: ReconstructingReducerStatement<'a>> ReconstructingDirector<'a, R> {
let argument = self.reduce_expression(argument.get());
self.reducer.reduce_console_assert(input, argument)
}
ConsoleFunction::Debug(f) | ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => {
ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => {
let formatted = self.reduce_formatted_string(f.clone());
self.reducer.reduce_console_log(input, formatted)
}

View File

@ -300,7 +300,6 @@ pub trait ReconstructingReducerStatement<'a>: ReconstructingReducerExpression<'a
span: input.span,
function: match input.function {
ConsoleFunction::Assert(_) => unimplemented!(),
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(argument),
ConsoleFunction::Error(_) => ConsoleFunction::Error(argument),
ConsoleFunction::Log(_) => ConsoleFunction::Log(argument),
},

View File

@ -336,9 +336,7 @@ impl<'a, R: StatementVisitor<'a>> VisitorDirector<'a, R> {
VisitResult::VisitChildren => {
match &input.function {
ConsoleFunction::Assert(e) => self.visit_expression(e)?,
ConsoleFunction::Debug(f) | ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => {
self.visit_formatted_string(f)?
}
ConsoleFunction::Error(f) | ConsoleFunction::Log(f) => self.visit_formatted_string(f)?,
}
Ok(())
}

View File

@ -30,7 +30,6 @@ pub struct ConsoleArgs<'a> {
#[derive(Clone)]
pub enum ConsoleFunction<'a> {
Assert(Cell<&'a Expression<'a>>),
Debug(ConsoleArgs<'a>),
Error(ConsoleArgs<'a>),
Log(ConsoleArgs<'a>),
}
@ -89,7 +88,6 @@ impl<'a> FromAst<'a, leo_ast::ConsoleStatement> for ConsoleStatement<'a> {
AstConsoleFunction::Assert(expression) => ConsoleFunction::Assert(Cell::new(
<&Expression<'a>>::from_ast(scope, expression, Some(Type::Boolean.into()))?,
)),
AstConsoleFunction::Debug(args) => ConsoleFunction::Debug(ConsoleArgs::from_ast(scope, args, None)?),
AstConsoleFunction::Error(args) => ConsoleFunction::Error(ConsoleArgs::from_ast(scope, args, None)?),
AstConsoleFunction::Log(args) => ConsoleFunction::Log(ConsoleArgs::from_ast(scope, args, None)?),
},
@ -103,7 +101,6 @@ impl<'a> Into<leo_ast::ConsoleStatement> for &ConsoleStatement<'a> {
leo_ast::ConsoleStatement {
function: match &self.function {
Assert(e) => AstConsoleFunction::Assert(e.get().into()),
Debug(args) => AstConsoleFunction::Debug(args.into()),
Error(args) => AstConsoleFunction::Error(args.into()),
Log(args) => AstConsoleFunction::Log(args.into()),
},

View File

@ -1,3 +0,0 @@
function main() {
console.debug("hello debug");
}

View File

@ -40,14 +40,6 @@ fn test_log_input() {
load_asg(program_string).unwrap();
}
// Debug
#[test]
fn test_debug() {
let program_string = include_str!("debug.leo");
load_asg(program_string).unwrap();
}
// Error
#[test]

View File

@ -1,6 +1,6 @@
[package]
name = "leo-ast"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Core AST of the Leo programming language"
homepage = "https://aleo.org"
@ -19,7 +19,7 @@ edition = "2018"
[dependencies.leo-input]
path = "../input"
version = "1.5.2"
version = "1.5.3"
[dependencies.indexmap]
version = "1.7.0"

View File

@ -15,7 +15,6 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{LeoError, Span};
use std::{fmt, sync::Arc};
pub const INDENT: &str = " ";
@ -77,20 +76,21 @@ impl fmt::Display for FormattedError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let underline = underline(self.col_start, self.col_stop);
write!(
f,
let error_message = format!(
"{indent }--> {path}:{line_start}:{start}\n\
{indent } |\n",
{indent } ",
indent = INDENT,
path = &*self.path,
line_start = self.line_start,
start = self.col_start,
)?;
);
write!(f, "{}", error_message)?;
for (line_no, line) in self.content.lines().enumerate() {
writeln!(
f,
"{line_no:width$} | {text}",
"|\n{line_no:width$} | {text}",
width = INDENT.len(),
line_no = self.line_start + line_no,
text = line,

View File

@ -392,7 +392,7 @@ impl Canonicalizer {
ConsoleFunction::Assert(expression) => {
ConsoleFunction::Assert(self.canonicalize_expression(expression))
}
ConsoleFunction::Debug(args) | ConsoleFunction::Error(args) | ConsoleFunction::Log(args) => {
ConsoleFunction::Error(args) | ConsoleFunction::Log(args) => {
let parameters = args
.parameters
.iter()
@ -406,7 +406,6 @@ impl Canonicalizer {
};
match &console_function_call.function {
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(console_args),
ConsoleFunction::Error(_) => ConsoleFunction::Error(console_args),
ConsoleFunction::Log(_) => ConsoleFunction::Log(console_args),
_ => unimplemented!(), // impossible

View File

@ -390,7 +390,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
) -> Result<ConsoleStatement, ReducerError> {
let function = match &console_function_call.function {
ConsoleFunction::Assert(expression) => ConsoleFunction::Assert(self.reduce_expression(expression)?),
ConsoleFunction::Debug(args) | ConsoleFunction::Error(args) | ConsoleFunction::Log(args) => {
ConsoleFunction::Error(args) | ConsoleFunction::Log(args) => {
let mut parameters = vec![];
for parameter in args.parameters.iter() {
parameters.push(self.reduce_expression(parameter)?);
@ -403,7 +403,6 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
};
match &console_function_call.function {
ConsoleFunction::Debug(_) => ConsoleFunction::Debug(formatted),
ConsoleFunction::Error(_) => ConsoleFunction::Error(formatted),
ConsoleFunction::Log(_) => ConsoleFunction::Log(formatted),
_ => return Err(ReducerError::impossible_console_assert_call(&args.span)),

View File

@ -22,7 +22,6 @@ use std::fmt;
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum ConsoleFunction {
Assert(Expression),
Debug(ConsoleArgs),
Error(ConsoleArgs),
Log(ConsoleArgs),
}
@ -31,7 +30,6 @@ impl fmt::Display for ConsoleFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ConsoleFunction::Assert(assert) => write!(f, "assert({})", assert),
ConsoleFunction::Debug(debug) => write!(f, "debug({})", debug),
ConsoleFunction::Error(error) => write!(f, "error{})", error),
ConsoleFunction::Log(log) => write!(f, "log({})", log),
}
@ -42,18 +40,14 @@ impl Node for ConsoleFunction {
fn span(&self) -> &Span {
match self {
ConsoleFunction::Assert(assert) => assert.span(),
ConsoleFunction::Debug(formatted) | ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => {
&formatted.span
}
ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => &formatted.span,
}
}
fn set_span(&mut self, span: Span) {
match self {
ConsoleFunction::Assert(assert) => assert.set_span(span),
ConsoleFunction::Debug(formatted) | ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => {
formatted.set_span(span)
}
ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => formatted.set_span(span),
}
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "leo-compiler"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Compiler of the Leo programming language"
homepage = "https://aleo.org"
@ -19,39 +19,39 @@ edition = "2018"
[dependencies.leo-ast]
path = "../ast"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-imports]
path = "../imports"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-input]
path = "../input"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-package]
path = "../package"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-state]
path = "../state"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-asg]
path = "../asg"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-parser]
path = "../parser"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-asg-passes]
path = "../asg-passes"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-synthesizer]
path = "../synthesizer"
version = "1.5.2"
version = "1.5.3"
[dependencies.tendril]
version = "0.4"
@ -71,7 +71,7 @@ default-features = false
[dependencies.snarkvm-gadgets]
version = "0.7.5"
default-features = false
features = ["curves"]
features = [ "curves" ]
[dependencies.snarkvm-r1cs]
version = "0.7.5"

View File

@ -39,13 +39,6 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
&console.span.clone().unwrap_or_default(),
)?;
}
ConsoleFunction::Debug(string) => {
let string = self.format(cs, string)?;
if get_indicator_value(indicator) {
tracing::debug!("{}", string);
}
}
ConsoleFunction::Error(string) => {
let string = self.format(cs, string)?;

View File

@ -597,8 +597,7 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
(AstConsoleFunction::Assert(ast_expression), AsgConsoleFunction::Assert(asg_expression)) => {
AstConsoleFunction::Assert(self.reduce_expression(&ast_expression, asg_expression.get())?)
}
(AstConsoleFunction::Debug(ast_console_args), AsgConsoleFunction::Debug(asg_format))
| (AstConsoleFunction::Error(ast_console_args), AsgConsoleFunction::Error(asg_format))
(AstConsoleFunction::Error(ast_console_args), AsgConsoleFunction::Error(asg_format))
| (AstConsoleFunction::Log(ast_console_args), AsgConsoleFunction::Log(asg_format)) => {
let mut parameters = vec![];
for (ast_parameter, asg_parameter) in
@ -614,7 +613,6 @@ impl<R: ReconstructingReducer, O: CombinerOptions> CombineAstAsgDirector<R, O> {
};
match &ast.function {
AstConsoleFunction::Debug(_) => AstConsoleFunction::Debug(args),
AstConsoleFunction::Error(_) => AstConsoleFunction::Error(args),
AstConsoleFunction::Log(_) => AstConsoleFunction::Log(args),
_ => return Err(ReducerError::impossible_console_assert_call(&ast_console_args.span)),

View File

@ -235,7 +235,9 @@ impl Namespace for CompileNamespace {
.unwrap_or_else(|_| "Error converting ast to string.".to_string()),
);
std::fs::remove_dir_all(std::path::Path::new("/tmp/output")).expect("Error failed to clean up output dir.");
if std::fs::read_dir("/tmp/output").is_ok() {
std::fs::remove_dir_all(std::path::Path::new("/tmp/output")).expect("Error failed to clean up output dir.");
}
let final_output = CompileOutput {
circuit: last_circuit.unwrap(),

View File

@ -85,33 +85,57 @@ impl Address {
Ok(ConstrainedValue::Address(address))
}
pub(crate) fn alloc_helper<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>>(
pub(crate) fn alloc_helper<
F: PrimeField,
CS: ConstraintSystem<F>,
Fn: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<String>,
>(
cs: CS,
value_gen: Fn,
) -> Result<AleoAddress<Components>, SynthesisError> {
let address_string = match value_gen() {
Ok(value) => {
let string_value = value.borrow().clone();
Ok(string_value)
}
_ => Err(SynthesisError::AssignmentMissing),
}?;
AleoAddress::from_str(&address_string).map_err(|_| SynthesisError::AssignmentMissing)
if cs.is_in_setup_mode() {
Ok(AleoAddress::<Components>::default())
} else {
let address_string = value_gen()?.borrow().clone();
AleoAddress::from_str(&address_string).map_err(|_| SynthesisError::AssignmentMissing)
}
}
}
impl<F: PrimeField> AllocGadget<String, F> for Address {
fn alloc<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
cs: CS,
fn alloc_constant<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
_cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let address = Self::alloc_helper(value_gen)?;
let address = {
let address_string = value_gen()?.borrow().clone();
AleoAddress::from_str(&address_string).map_err(|_| SynthesisError::AssignmentMissing)?
};
let mut address_bytes = vec![];
address
.write_le(&mut address_bytes)
.map_err(|_| SynthesisError::AssignmentMissing)?;
let bytes = UInt8::alloc_vec(cs, &address_bytes[..])?;
let bytes = UInt8::constant_vec(&address_bytes[..]);
Ok(Address {
address: Some(address),
bytes,
})
}
fn alloc<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
mut cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let address = Self::alloc_helper(cs.ns(|| "allocate the address"), value_gen)?;
let mut address_bytes = vec![];
address
.write_le(&mut address_bytes)
.map_err(|_| SynthesisError::AssignmentMissing)?;
let bytes = UInt8::alloc_vec(cs.ns(|| "allocate the address bytes"), &address_bytes[..])?;
Ok(Address {
address: Some(address),
@ -120,16 +144,16 @@ impl<F: PrimeField> AllocGadget<String, F> for Address {
}
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
cs: CS,
mut cs: CS,
value_gen: Fn,
) -> Result<Self, SynthesisError> {
let address = Self::alloc_helper(value_gen)?;
let address = Self::alloc_helper(cs.ns(|| "allocate the address"), value_gen)?;
let mut address_bytes = vec![];
address
.write_le(&mut address_bytes)
.map_err(|_| SynthesisError::AssignmentMissing)?;
let bytes = UInt8::alloc_input_vec_le(cs, &address_bytes[..])?;
let bytes = UInt8::alloc_input_vec_le(cs.ns(|| "allocate the address bytes"), &address_bytes[..])?;
Ok(Address {
address: Some(address),

View File

@ -120,6 +120,15 @@ Thus, this RFC also proposed to extend Leo with such an operator.
A possibility is `<expression>.length`, where `<expression>` is an expression of array type.
A variation is `<expression>.length()`, if we want it look more like a built-in method on arrays.
Yet another option is `length(<expression>)`, which is more like a built-in function.
A shorter name could be `len`, leading to the three possibilities
`<expression>.len`, `<expression>.len()`, and `len(<expression>)`.
So one dimension of the choice is the name (`length` vs. `len`),
and another dimension is the style:
member variable style,
member function style,
or global function style.
The decision on the latter should be driven by broader considerations
of how we want to treat this kind of built-in operators.
Note that the result of this operator can, and in fact must, be calculated at compile time;
not as part of the Leo interpreter, but rather as part of the flattening of Leo to R1CS.

View File

@ -0,0 +1,162 @@
# Leo RFC 007: Type Aliases
## Authors
- Max Bruce
- Collin Chin
- Alessandro Coglio
- Eric McCarthy
- Jon Pavlik
- Damir Shamanaev
- Damon Sicore
- Howard Wu
## Status
DRAFT
# Summary
This RFC proposes the addition of type aliases to Leo,
i.e. identifiers that abbreviate types and can be used wherever the latter can be used.
A new top-level construct is proposed to define type aliases; no circularities are allowed.
Type aliases are expanded away during compilation.
# Motivation
Many programming languages provide the ability to create aliases (i.e. synonyms) of types, such as C's `typedef`.
The purpose may be to abbreviate a longer type,
such as an alias `matrix` for `[i32; (3, 3)]` in an application in which 3x3 matrices of 32-bit integers are relevant
(e.g. for 3-D rotations, even though fractional numbers may be more realistic).
The purpose may also be to clarify the purpose and use of an existing type,
such as an alias `balance` for `u64` in an application that keeps track of balances.
The initial motivation that inspired this RFC (along with other RFCs)
was the ability to have a type `string` for strings.
Strings are arrays of characters according to RFC 001.
With the array types of unspecified size proposed in RFC 006,
`[char; _]` becomes a generic type for strings, which is desirable to alias with `string`.
# Design
## Syntax
The ABNF grammar changes as follows:
```ts
; modified rule:
keyword = ...
/ %s"true"
/ %s"type" ; new
/ %s"u8"
/ ...
; new rule:
type-alias-declaration = %s"type" identifier "=" type ";"
; modified rule:
declaration = import-declaration
/ function-declaration
/ circuit-declaration
/ constant-declaration
/ type-alias-declaration ; new
```
A type alias declaration introduces the identifier to stand for the type.
Only top-level type alias declarations are supported;
they are not supported inside functions or circuit types.
## Semantics
There must be no direct or indirect circularity in the type aliases.
That is, it must be possible to expand all the type aliases away,
obtaining an equivalent program without any type aliases.
Note that the built-in `Self` is a bit like a type alias, standing for the enclosing circuit type;
and `Self` is replaced with the enclosing circuit type during canonicalization.
Thus, canonicalization could be a natural place to expand user-defined type aliases;
after all, type aliases introduce multiple ways to denote the same types
(and not just via direct aliasing, but also via indirect aliasing, or via aliasing of components),
and canonicalization serves exactly to reduce multiple ways to say the same thing to one canonical way.
On the other hand, expanding type aliases is more complicated than the current canonicalization transformations,
which are all local and relatively simple.
Expanding type aliases requires not only checking for circularities,
but also to take into account references to type aliases from import declarations.
For this reason, we may perform type alias expansion after canonicalization,
such as just before type checking and inference.
We could also make the expansion a part of the type checking and inference process,
which already transforms the program by inferring missing types,
so it could also expand type aliases away.
In any case, it seems beneficial to expand type aliases away
(whether during canonicalization or as part or preamble to type checking and inference)
prior to performing more processing of the program for eventual compilation to R1CS.
## Examples
The aforementioned 3x3 matrix example could be written as follows:
```ts
type matrix = [u32; (3, 3)];
function matrix_multiply(x: matrix, y: matrix) -> matrix {
...
}
```
The aforementioned balance example could be written as follows:
```ts
type balance = u64;
function f(...) -> (..., balance, ...) {
...
}
```
The aforementioned string example could be written as follows:
```ts
type string = [char; _];
function f(str: string) -> ... {
...
}
```
# Drawbacks
As other extensions of the language, this makes things inherently a bit more complicated.
# Effect on Ecosystem
None; this is just a convenience for the Leo developer.
# Alternatives
An alternative to creating a type alias
```ts
type T = U;
```
is to create a circuit type
```ts
circuit T { get: U }
```
that contains a single member variable.
This is clearly not equivalent to a type alias, because it involves conversions between `T` and `U`
```ts
T { get: u } // convert u:U to T
t.get // convert t:T to U
```
whereas a type alias involves no conversions:
if `T` is an alias of `U`, then `T` and `U` are the same type,
more precisely two syntactically different ways to designate the same semantic type.
While the conversions generally cause overhead in traditional programming languages,
this may not be the case for Leo's compilation to R1CS,
in which everything is flattened, including member variables of circuit types.
Thus, it may be the case that the circuit `T` above reduces to just its member `U` in R1CS.
It might also be argued that wrapping a type into a one-member-variable circuit type
could be a better practice than aliasing the type, to enforce better type separation and safety.
We need to consider the pros and cons of the two approaches,
particularly in light of Leo's non-traditional compilation target.

View File

@ -0,0 +1,82 @@
# Leo RFC 008: Built-in Declarations
## Authors
- Max Bruce
- Collin Chin
- Alessandro Coglio
- Eric McCarthy
- Jon Pavlik
- Damir Shamanaev
- Damon Sicore
- Howard Wu
## Status
DRAFT
# Summary
This RFC proposes a framework for making certain (top-level) declarations (e.g. type aliases)
available in every Leo program without the need to explicitly write those declarations.
These may be hardwired into the language, or provided by standard libraries/packages;
in the latter case, the libraries may be either implicitly imported or required to be explicitly imported.
# Motivation
It is common for programming languages to provide predefined types, functions, etc.
that can be readily used in programs.
The initial motivation for this in Leo was to have a type alias `string` for character arrays of unspecified sizes
(array types of unspecified sizes and type aliases are discussed in separate RFCs),
but the feature is clearly more general.
# Design
Leo supports four kinds of top-level declarations:
- Import declarations.
- Function declarations.
- Circuit type declarations.
- Global constant declarations.
- Type alias declarations. (Proposed in a separate RFC.)
Leaving import declarations aside for the moment since they are "meta" in some sense
(as they bring in names of entities declared elsewhere),
it may make sense for any of the four kinds of declarations above to have built-in instances,
i.e. we could have some built-in functions, circuit types, global constants, and type aliases.
This is why this RFC talks of built-in declarations, more broadly than just built-in type aliases that inspired it.
The built-in status of the envisioned declarations could be achieved in slightly different ways:
1. Their names could be simply available in any program,
without any explicit declaration found anywhere for them.
2. They could be declared in some core library files explicitly,
and be available in any program without needing to be explicitly import them,
like `java.lang.String` in Java or `std::Option` in Rust.
3. They could be declared in some core library files explicitly,
and be available only in programs that explicitly import them.
From a user's perspective, there is not a lot of difference between cases 1 and 2 above:
in both cases, the names are available; the only difference is that in case 2 the user can see the declaration somewhere.
Also note that case 2 could be seen as having an implicit (i.e. built-in) import of the library/libraries in question.
Again, imports are "meta" in this context, and what counts are really the other kinds of declarations.
In cases 2 and 3, a related but somewhat independent issue is whether those declarations have Leo definitions or not.
The Leo library already includes functions like the one for BLAKE2s that are not defined in Leo,
but rather "natively" in Rust/R1CS.
# Drawbacks
This does not seem to bring any drawbacks.
# Effect on Ecosystem
This may interact with libraries and packages in some way,
if we go with case 2 or 3 above.
But it should be not much different from regular libraries/packages.
# Alternatives
The 'Design' section above currently discusses a few alternatives,
rather than prescribing a defined approach.
When consensus is reached on one of the alternatives discussed there,
the others will be moved to this section.

View File

@ -1,6 +1,6 @@
[package]
name = "leo-abnf"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "ABNF to Markdown converter for the Leo programming language"
homepage = "https://aleo.org"

View File

@ -511,7 +511,7 @@ rest-of-block-comment = "*" rest-of-block-comment-after-star
/ not-star rest-of-block-comment
```
Go to: _[rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star](#user-content-not-star)_;
Go to: _[not-star](#user-content-not-star), [rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_;
<a name="rest-of-block-comment-after-star"></a>
@ -521,7 +521,7 @@ rest-of-block-comment-after-star = "/"
/ not-star-or-slash rest-of-block-comment
```
Go to: _[not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment](#user-content-rest-of-block-comment), [rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star)_;
Go to: _[rest-of-block-comment-after-star](#user-content-rest-of-block-comment-after-star), [not-star-or-slash](#user-content-not-star-or-slash), [rest-of-block-comment](#user-content-rest-of-block-comment)_;
<a name="end-of-line-comment"></a>
@ -772,7 +772,7 @@ character-literal-element = not-single-quote-or-backslash
/ unicode-character-escape
```
Go to: _[simple-character-escape](#user-content-simple-character-escape), [unicode-character-escape](#user-content-unicode-character-escape), [not-single-quote-or-backslash](#user-content-not-single-quote-or-backslash), [ascii-character-escape](#user-content-ascii-character-escape)_;
Go to: _[unicode-character-escape](#user-content-unicode-character-escape), [simple-character-escape](#user-content-simple-character-escape), [not-single-quote-or-backslash](#user-content-not-single-quote-or-backslash), [ascii-character-escape](#user-content-ascii-character-escape)_;
<a name="single-quote-escape"></a>
@ -827,7 +827,7 @@ simple-character-escape = single-quote-escape
/ null-character-escape
```
Go to: _[carriage-return-escape](#user-content-carriage-return-escape), [single-quote-escape](#user-content-single-quote-escape), [backslash-escape](#user-content-backslash-escape), [line-feed-escape](#user-content-line-feed-escape), [horizontal-tab-escape](#user-content-horizontal-tab-escape), [null-character-escape](#user-content-null-character-escape), [double-quote-escape](#user-content-double-quote-escape)_;
Go to: _[horizontal-tab-escape](#user-content-horizontal-tab-escape), [backslash-escape](#user-content-backslash-escape), [null-character-escape](#user-content-null-character-escape), [line-feed-escape](#user-content-line-feed-escape), [single-quote-escape](#user-content-single-quote-escape), [double-quote-escape](#user-content-double-quote-escape), [carriage-return-escape](#user-content-carriage-return-escape)_;
<a name="ascii-character-escape"></a>
@ -835,7 +835,7 @@ Go to: _[carriage-return-escape](#user-content-carriage-return-escape), [single-
ascii-character-escape = %s"\x" octal-digit hexadecimal-digit
```
Go to: _[hexadecimal-digit](#user-content-hexadecimal-digit), [octal-digit](#user-content-octal-digit)_;
Go to: _[octal-digit](#user-content-octal-digit), [hexadecimal-digit](#user-content-hexadecimal-digit)_;
<a name="unicode-character-escape"></a>
@ -863,7 +863,7 @@ string-literal-element = not-double-quote-or-backslash
/ unicode-character-escape
```
Go to: _[not-double-quote-or-backslash](#user-content-not-double-quote-or-backslash), [simple-character-escape](#user-content-simple-character-escape), [unicode-character-escape](#user-content-unicode-character-escape), [ascii-character-escape](#user-content-ascii-character-escape)_;
Go to: _[not-double-quote-or-backslash](#user-content-not-double-quote-or-backslash), [simple-character-escape](#user-content-simple-character-escape), [ascii-character-escape](#user-content-ascii-character-escape), [unicode-character-escape](#user-content-unicode-character-escape)_;
The ones above are all the atomic literals
@ -883,7 +883,7 @@ atomic-literal = untyped-literal
/ string-literal
```
Go to: _[string-literal](#user-content-string-literal), [product-group-literal](#user-content-product-group-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [address-literal](#user-content-address-literal), [boolean-literal](#user-content-boolean-literal), [untyped-literal](#user-content-untyped-literal), [character-literal](#user-content-character-literal), [signed-literal](#user-content-signed-literal)_;
Go to: _[signed-literal](#user-content-signed-literal), [unsigned-literal](#user-content-unsigned-literal), [field-literal](#user-content-field-literal), [product-group-literal](#user-content-product-group-literal), [boolean-literal](#user-content-boolean-literal), [address-literal](#user-content-address-literal), [string-literal](#user-content-string-literal), [untyped-literal](#user-content-untyped-literal), [character-literal](#user-content-character-literal)_;
After defining the (mostly) alphanumeric tokens above,
@ -927,7 +927,17 @@ token = keyword
/ symbol
```
Go to: _[atomic-literal](#user-content-atomic-literal), [identifier](#user-content-identifier), [symbol](#user-content-symbol), [package-name](#user-content-package-name), [annotation-name](#user-content-annotation-name), [keyword](#user-content-keyword)_;
Go to: _[atomic-literal](#user-content-atomic-literal), [package-name](#user-content-package-name), [annotation-name](#user-content-annotation-name), [symbol](#user-content-symbol), [identifier](#user-content-identifier), [keyword](#user-content-keyword)_;
Tokens, comments, and whitespace are lexemes, i.e. lexical units.
<a name="lexeme"></a>
```abnf
lexeme = token / comment / whitespace
```
Go to: _[whitespace](#user-content-whitespace), [comment](#user-content-comment), [token](#user-content-token)_;
@ -984,7 +994,7 @@ group-type = %s"group"
arithmetic-type = integer-type / field-type / group-type
```
Go to: _[field-type](#user-content-field-type), [group-type](#user-content-group-type), [integer-type](#user-content-integer-type)_;
Go to: _[integer-type](#user-content-integer-type), [field-type](#user-content-field-type), [group-type](#user-content-group-type)_;
The arithmetic types, along with the boolean, address, and character types,
@ -1050,7 +1060,7 @@ or a tuple of one or more dimensions.
array-type = "[" type ";" array-dimensions "]"
```
Go to: _[array-dimensions](#user-content-array-dimensions), [type](#user-content-type)_;
Go to: _[type](#user-content-type), [array-dimensions](#user-content-array-dimensions)_;
<a name="array-dimensions"></a>
@ -1071,7 +1081,7 @@ i.e. types whose values contain (sub-)values
aggregate-type = tuple-type / array-type / circuit-type
```
Go to: _[tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type), [circuit-type](#user-content-circuit-type)_;
Go to: _[circuit-type](#user-content-circuit-type), [tuple-type](#user-content-tuple-type), [array-type](#user-content-array-type)_;
Scalar and aggregate types form all the types.
@ -1081,7 +1091,7 @@ Scalar and aggregate types form all the types.
type = scalar-type / aggregate-type
```
Go to: _[aggregate-type](#user-content-aggregate-type), [scalar-type](#user-content-scalar-type)_;
Go to: _[scalar-type](#user-content-scalar-type), [aggregate-type](#user-content-aggregate-type)_;
The lexical grammar given earlier defines product group literals.
@ -1159,7 +1169,7 @@ primary-expression = identifier
/ circuit-expression
```
Go to: _[tuple-expression](#user-content-tuple-expression), [literal](#user-content-literal), [expression](#user-content-expression), [circuit-expression](#user-content-circuit-expression), [identifier](#user-content-identifier), [array-expression](#user-content-array-expression)_;
Go to: _[expression](#user-content-expression), [array-expression](#user-content-array-expression), [literal](#user-content-literal), [identifier](#user-content-identifier), [circuit-expression](#user-content-circuit-expression), [tuple-expression](#user-content-tuple-expression)_;
Tuple expressions construct tuples.
@ -1220,7 +1230,7 @@ Go to: _[expression](#user-content-expression), [array-dimensions](#user-content
array-construction = array-inline-construction / array-repeat-construction
```
Go to: _[array-repeat-construction](#user-content-array-repeat-construction), [array-inline-construction](#user-content-array-inline-construction)_;
Go to: _[array-inline-construction](#user-content-array-inline-construction), [array-repeat-construction](#user-content-array-repeat-construction)_;
<a name="array-expression"></a>
@ -1248,7 +1258,7 @@ circuit-construction = circuit-type "{"
"}"
```
Go to: _[circuit-inline-element](#user-content-circuit-inline-element), [circuit-type](#user-content-circuit-type)_;
Go to: _[circuit-type](#user-content-circuit-type), [circuit-inline-element](#user-content-circuit-inline-element)_;
<a name="circuit-inline-element"></a>
@ -1307,7 +1317,7 @@ postfix-expression = primary-expression
/ postfix-expression "[" [expression] ".." [expression] "]"
```
Go to: _[circuit-type](#user-content-circuit-type), [postfix-expression](#user-content-postfix-expression), [primary-expression](#user-content-primary-expression), [identifier](#user-content-identifier), [function-arguments](#user-content-function-arguments), [natural](#user-content-natural), [expression](#user-content-expression)_;
Go to: _[natural](#user-content-natural), [identifier](#user-content-identifier), [circuit-type](#user-content-circuit-type), [primary-expression](#user-content-primary-expression), [function-arguments](#user-content-function-arguments), [postfix-expression](#user-content-postfix-expression), [expression](#user-content-expression)_;
Unary operators have the highest operator precedence.
@ -1321,7 +1331,7 @@ unary-expression = postfix-expression
/ "-" unary-expression
```
Go to: _[unary-expression](#user-content-unary-expression), [postfix-expression](#user-content-postfix-expression)_;
Go to: _[postfix-expression](#user-content-postfix-expression), [unary-expression](#user-content-unary-expression)_;
Next in the operator precedence is exponentiation,
@ -1347,7 +1357,7 @@ multiplicative-expression = exponential-expression
/ multiplicative-expression "/" exponential-expression
```
Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [exponential-expression](#user-content-exponential-expression)_;
Go to: _[exponential-expression](#user-content-exponential-expression), [multiplicative-expression](#user-content-multiplicative-expression)_;
Then there are addition and subtraction, both left-assocative.
@ -1359,7 +1369,7 @@ additive-expression = multiplicative-expression
/ additive-expression "-" multiplicative-expression
```
Go to: _[multiplicative-expression](#user-content-multiplicative-expression), [additive-expression](#user-content-additive-expression)_;
Go to: _[additive-expression](#user-content-additive-expression), [multiplicative-expression](#user-content-multiplicative-expression)_;
Next in the precedence order are ordering relations.
@ -1398,7 +1408,7 @@ conjunctive-expression = equality-expression
/ conjunctive-expression "&&" equality-expression
```
Go to: _[conjunctive-expression](#user-content-conjunctive-expression), [equality-expression](#user-content-equality-expression)_;
Go to: _[equality-expression](#user-content-equality-expression), [conjunctive-expression](#user-content-conjunctive-expression)_;
Next come disjunctive expressions, left-associative.
@ -1409,7 +1419,7 @@ disjunctive-expression = conjunctive-expression
/ disjunctive-expression "||" conjunctive-expression
```
Go to: _[disjunctive-expression](#user-content-disjunctive-expression), [conjunctive-expression](#user-content-conjunctive-expression)_;
Go to: _[conjunctive-expression](#user-content-conjunctive-expression), [disjunctive-expression](#user-content-disjunctive-expression)_;
Finally we have conditional expressions.
@ -1422,7 +1432,7 @@ conditional-expression = disjunctive-expression
":" conditional-expression
```
Go to: _[expression](#user-content-expression), [conditional-expression](#user-content-conditional-expression), [disjunctive-expression](#user-content-disjunctive-expression)_;
Go to: _[expression](#user-content-expression), [disjunctive-expression](#user-content-disjunctive-expression), [conditional-expression](#user-content-conditional-expression)_;
Those above are all the expressions.
@ -1455,7 +1465,7 @@ statement = expression-statement
/ block
```
Go to: _[assignment-statement](#user-content-assignment-statement), [expression-statement](#user-content-expression-statement), [conditional-statement](#user-content-conditional-statement), [block](#user-content-block), [loop-statement](#user-content-loop-statement), [constant-declaration](#user-content-constant-declaration), [console-statement](#user-content-console-statement), [variable-declaration](#user-content-variable-declaration), [return-statement](#user-content-return-statement)_;
Go to: _[constant-declaration](#user-content-constant-declaration), [block](#user-content-block), [variable-declaration](#user-content-variable-declaration), [conditional-statement](#user-content-conditional-statement), [return-statement](#user-content-return-statement), [assignment-statement](#user-content-assignment-statement), [expression-statement](#user-content-expression-statement), [loop-statement](#user-content-loop-statement), [console-statement](#user-content-console-statement)_;
<a name="block"></a>
@ -1498,7 +1508,7 @@ variable-declaration = %s"let" identifier-or-identifiers [ ":" type ]
"=" expression ";"
```
Go to: _[expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type)_;
Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_;
<a name="constant-declaration"></a>
@ -1507,7 +1517,7 @@ constant-declaration = %s"const" identifier-or-identifiers [ ":" type ]
"=" expression ";"
```
Go to: _[type](#user-content-type), [expression](#user-content-expression), [identifier-or-identifiers](#user-content-identifier-or-identifiers)_;
Go to: _[identifier-or-identifiers](#user-content-identifier-or-identifiers), [type](#user-content-type), [expression](#user-content-expression)_;
<a name="identifier-or-identifiers"></a>
@ -1530,7 +1540,7 @@ Note that blocks are required in all branches, not merely statements.
branch = %s"if" expression block
```
Go to: _[expression](#user-content-expression), [block](#user-content-block)_;
Go to: _[block](#user-content-block), [expression](#user-content-expression)_;
<a name="conditional-statement"></a>
@ -1596,7 +1606,7 @@ console-call = assert-call
/ print-call
```
Go to: _[print-call](#user-content-print-call), [assert-call](#user-content-assert-call)_;
Go to: _[assert-call](#user-content-assert-call), [print-call](#user-content-print-call)_;
<a name="assert-call"></a>
@ -1638,7 +1648,7 @@ annotation = annotation-name
[ "(" identifier *( "," identifier ) ")" ]
```
Go to: _[identifier](#user-content-identifier), [annotation-name](#user-content-annotation-name)_;
Go to: _[annotation-name](#user-content-annotation-name), [identifier](#user-content-identifier)_;
A function declaration defines a function.
@ -1655,7 +1665,7 @@ function-declaration = *annotation %s"function" identifier
block
```
Go to: _[type](#user-content-type), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters), [block](#user-content-block)_;
Go to: _[block](#user-content-block), [identifier](#user-content-identifier), [function-parameters](#user-content-function-parameters), [type](#user-content-type)_;
<a name="function-parameters"></a>
@ -1665,7 +1675,7 @@ function-parameters = self-parameter
/ function-inputs
```
Go to: _[self-parameter](#user-content-self-parameter), [function-inputs](#user-content-function-inputs)_;
Go to: _[function-inputs](#user-content-function-inputs), [self-parameter](#user-content-self-parameter)_;
<a name="self-parameter"></a>
@ -1706,7 +1716,7 @@ member-variable-declarations = *( identifier ":" type ( "," / ";" ) )
identifier ":" type ( [ "," ] / ";" )
```
Go to: _[identifier](#user-content-identifier), [type](#user-content-type)_;
Go to: _[type](#user-content-type), [identifier](#user-content-identifier)_;
A circuit member function declaration consists of a function declaration.
@ -1756,7 +1766,7 @@ by using an explicit package name before the package path.
import-declaration = %s"import" package-name "." package-path ";"
```
Go to: _[package-name](#user-content-package-name), [package-path](#user-content-package-path)_;
Go to: _[package-path](#user-content-package-path), [package-name](#user-content-package-name)_;
<a name="package-path"></a>
@ -1782,7 +1792,7 @@ declaration = import-declaration
/ constant-declaration
```
Go to: _[circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration), [function-declaration](#user-content-function-declaration)_;
Go to: _[function-declaration](#user-content-function-declaration), [circuit-declaration](#user-content-circuit-declaration), [constant-declaration](#user-content-constant-declaration), [import-declaration](#user-content-import-declaration)_;
<a name="file"></a>

View File

@ -611,6 +611,10 @@ token = keyword
/ annotation-name
/ symbol
; Tokens, comments, and whitespace are lexemes, i.e. lexical units.
lexeme = token / comment / whitespace
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Syntactic Grammar

View File

@ -1,6 +1,6 @@
[package]
name = "leo-imports"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Import parser for Leo program package dependencies"
homepage = "https://aleo.org"
@ -19,15 +19,15 @@ edition = "2018"
[dependencies.leo-ast]
path = "../ast"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-asg]
path = "../asg"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-parser]
path = "../parser"
version = "1.5.2"
version = "1.5.3"
[dependencies.indexmap]
version = "1.7.0"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-input"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Input parser of the Leo programming language"
homepage = "https://aleo.org"

View File

@ -218,6 +218,11 @@ pub fn init_logger(_app_name: &'static str, verbosity: usize) -> Result<()> {
Err(_) => return Err(anyhow::anyhow!("Error: Failed to enable ansi_support")),
};
use tracing_subscriber::fmt::writer::MakeWriterExt;
let stderr = std::io::stderr.with_max_level(tracing::Level::WARN);
let mk_writer = stderr.or_else(std::io::stdout);
let subscriber = FmtSubscriber::builder()
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
// will be written to stdout.
@ -227,6 +232,7 @@ pub fn init_logger(_app_name: &'static str, verbosity: usize) -> Result<()> {
2 => tracing::Level::DEBUG,
_ => tracing::Level::TRACE
})
.with_writer(mk_writer)
.without_time()
.with_target(false)
.event_format(Format::default())

View File

@ -39,6 +39,7 @@ use commands::{
};
use anyhow::Result;
use colored::Colorize;
use std::{path::PathBuf, process::exit};
use structopt::{clap::AppSettings, StructOpt};
@ -233,7 +234,20 @@ fn handle_error<T>(res: Result<T>) -> T {
match res {
Ok(t) => t,
Err(err) => {
eprintln!("Error: {}", err);
eprintln!(
"{} {}",
"Error:".bold().red(),
err.to_string()
.lines()
.enumerate()
.map(|(i, l)| if i == 0 {
l.bold().red().to_string()
} else {
l.to_string()
})
.collect::<Vec<_>>()
.join("\n")
);
exit(1);
}
}

View File

@ -2,7 +2,7 @@ dependencies = { }
[package]
name = "leo-linter"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Linter of the Leo programming language"
homepage = "https://aleo.org"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-package"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Package parser of the Leo programming language"
homepage = "https://aleo.org"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-parser"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "AST generated by pest from the Leo grammar rules"
homepage = "https://aleo.org"
@ -24,7 +24,7 @@ harness = false
[dependencies.leo-ast]
path = "../ast"
version = "1.5.2"
version = "1.5.3"
[dependencies.lazy_static]
version = "1.3.0"

View File

@ -277,13 +277,12 @@ impl ParserContext {
let expr = self.parse_expression()?;
ConsoleFunction::Assert(expr)
}
"debug" => ConsoleFunction::Debug(self.parse_console_args()?),
"error" => ConsoleFunction::Error(self.parse_console_args()?),
"log" => ConsoleFunction::Log(self.parse_console_args()?),
x => {
return Err(SyntaxError::unexpected_ident(
&x,
&["assert", "debug", "error", "log"],
&["assert", "error", "log"],
&function.span,
));
}

View File

@ -1,6 +1,6 @@
[package]
name = "leo-state"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "State parser of the Leo programming language"
homepage = "https://aleo.org"
@ -19,11 +19,11 @@ edition = "2018"
[dependencies.leo-input]
path = "../input"
version = "1.5.2"
version = "1.5.3"
[dependencies.leo-ast]
path = "../ast"
version = "1.5.2"
version = "1.5.3"
[dependencies.snarkvm-algorithms]
version = "0.7.4"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-synthesizer"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Circuit synthesizer of the Leo programming language"
homepage = "https://aleo.org"

View File

@ -1,6 +1,6 @@
[package]
name = "leo-test-framework"
version = "1.5.2"
version = "1.5.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Leo testing framework"
homepage = "https://aleo.org"

View File

@ -0,0 +1,15 @@
/*
namespace: Compile
expectation: Pass
input_file: inputs/branch.in
*/
function main (x: address, y: bool) -> bool {
let z = aleo18cw5zdez3zhypev3tnfhmwvhre9ramwle4up947gcyy5rnmjw5yqn93wsr;
if y {
z = aleo1f2gs8g0qpumlgzpvmkw3q07y6xrwsdr0lqsu9h9fgnh8d7e44v9qhpgpkj;
}
return z == aleo1f2gs8g0qpumlgzpvmkw3q07y6xrwsdr0lqsu9h9fgnh8d7e44v9qhpgpkj;
}

View File

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

View File

@ -0,0 +1,6 @@
[main]
x: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
y: bool = true;
[registers]
a: bool = false;

View File

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

View File

@ -1,10 +0,0 @@
/*
namespace: Compile
expectation: Pass
input_file: input/dummy.in
*/
function main(y: bool) -> bool {
console.debug("hello debug");
return y == true;
}

View File

@ -1,15 +1,14 @@
/*
namespace: Compile
expectation: Fail
input_file: input/integers.in
input_file: input/dummy.in
*/
function main(a: u32) -> u32 {
function main() {
console.log("{}", 1u8);
return 10u32;
}
function main() {
console.log("{}", 2u8);
console.log("{}", 2u8);
}

View File

@ -0,0 +1,21 @@
---
namespace: Compile
expectation: Pass
outputs:
- circuit:
num_public_variables: 0
num_private_variables: 1024
num_constraints: 1536
at: 5afd1d58b6826912fe5cba06b60d9a7debdbad9e922b8a78ed49f7a7ca0ac65e
bt: db77c3470cf1b3c80c2e3b1b3ddc59d9891912489bfcf39b7f67c2f314ca7f6d
ct: d0993682df5b495f4a6784882e0f007dbc378adb35007d250e2c098975f4d32e
output:
- input_file: inputs/branch.in
output:
registers:
a:
type: bool
value: "true"
initial_ast: a7748573e4731753b76889c6d4c28e9589e114860a163da87957cf20b916f733
canonicalized_ast: a7748573e4731753b76889c6d4c28e9589e114860a163da87957cf20b916f733
type_inferenced_ast: af3663710ad6278c3d2e28a753d62084505746cd49de11949fe5e8e390ffcc60

View File

@ -0,0 +1,21 @@
---
namespace: Compile
expectation: Pass
outputs:
- circuit:
num_public_variables: 0
num_private_variables: 1694
num_constraints: 2719
at: f9a9bc8304df327c7b16f088b61ac518fb3a7b6457ccc35a1ab9eab4565a1981
bt: 045eba0fdd405714f788492fd5914b053e0ece622e9a542270d8cfe85c0ee291
ct: e8fa4a33a657c70a7cecc7e9b284157b369b7ea57879948e108daf93e778551c
output:
- input_file: inputs/index.in
output:
registers:
a:
type: bool
value: "true"
initial_ast: 8934e4c1d645f6f98fe59f48bbf687623e811c99e504e87c6989bc00af62194a
canonicalized_ast: 8934e4c1d645f6f98fe59f48bbf687623e811c99e504e87c6989bc00af62194a
type_inferenced_ast: 70af835aeaec1d5bc1c4a3186635260ff44743e0d3a7aa5ac9f2c98ec03bd23e

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> compiler-test:6:19\n |\n 6 | const x = a[i..10];\n | ^^^^^^^^\n |\n = array size cannot be inferred, add explicit types"
- " --> compiler-test:7:17\n |\n 7 | console.debug(\"{}\", x);\n | ^^^^^\n |\n = expected identifier 'assert', 'error', 'log' -- got 'debug'"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> :0:0\n |\n |\n |\n = failed to resolve import: 'core'"
- " --> :0:0\n |\n |\n = failed to resolve import: 'core'"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> :0:0\n |\n |\n |\n = failed to resolve import: 'core'"
- " --> :0:0\n |\n |\n = failed to resolve import: 'core'"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> :0:0\n |\n |\n |\n = failed to resolve import: 'core.unstable'"
- " --> :0:0\n |\n |\n = failed to resolve import: 'core.unstable'"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> compiler-test:6:12\n |\n 6 | return 10u32; \n | ^^^^^\n |\n = unexpected type, expected: '()', received: 'u32'"
- " --> compiler-test:8:1\n |\n 8 | function main() {\n|\n 9 | ...\n|\n 10 | }\n | ^\n |\n = a function named \"main\" already exists in this scope"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> compiler-test:4:5\n |\n 4 | if true {\n 5 | ...\n 6 | }\n | ^\n |\n = function 'main' failed to validate return path: 'cannot have asymmetrical return in if statement'"
- " --> compiler-test:4:5\n |\n 4 | if true {\n|\n 5 | ...\n|\n 6 | }\n | ^\n |\n = function 'main' failed to validate return path: 'cannot have asymmetrical return in if statement'"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> compiler-test:3:1\n |\n 3 | function main() -> bool {\n 4 | ...\n 5 | }\n 6 | \n 7 | \n 8 | \n 9 | \n 10 | \n | ^\n |\n = function 'main' missing return for all paths"
- " --> compiler-test:3:1\n |\n 3 | function main() -> bool {\n|\n 4 | ...\n|\n 5 | }\n|\n 6 | \n|\n 7 | \n|\n 8 | \n|\n 9 | \n|\n 10 | \n | ^\n |\n = function 'main' missing return for all paths"

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- " --> compiler-test:3:1\n |\n 3 | function main() -> bool {\n 4 | ...\n 5 | }\n | ^\n |\n = Mismatched types. Expected register output type `u8`, found type `bool`."
- " --> compiler-test:3:1\n |\n 3 | function main() -> bool {\n|\n 4 | ...\n|\n 5 | }\n | ^\n |\n = Mismatched types. Expected register output type `u8`, found type `bool`."

View File

@ -80,73 +80,6 @@ outputs:
col_stop: 18
path: test
content: "console.error(\"x\");"
- Console:
function:
Debug:
string:
- Scalar: 123
- Scalar: 125
parameters:
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":21,\\\"col_stop\\\":22,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"console.debug(\\\\\\\"{}\\\\\\\", x);\\\"}\"}"
span:
line_start: 1
line_stop: 1
col_start: 15
col_stop: 22
path: test
content: "console.debug(\"{}\", x);"
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 22
path: test
content: "console.debug(\"{}\", x);"
- Console:
function:
Debug:
string:
- Scalar: 123
- Scalar: 125
- Scalar: 123
- Scalar: 125
parameters:
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":23,\\\"col_stop\\\":24,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"console.debug(\\\\\\\"{}{}\\\\\\\", x, y);\\\"}\"}"
- Identifier: "{\"name\":\"y\",\"span\":\"{\\\"line_start\\\":1,\\\"line_stop\\\":1,\\\"col_start\\\":26,\\\"col_stop\\\":27,\\\"path\\\":\\\"test\\\",\\\"content\\\":\\\"console.debug(\\\\\\\"{}{}\\\\\\\", x, y);\\\"}\"}"
span:
line_start: 1
line_stop: 1
col_start: 15
col_stop: 27
path: test
content: "console.debug(\"{}{}\", x, y);"
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 27
path: test
content: "console.debug(\"{}{}\", x, y);"
- Console:
function:
Debug:
string:
- Scalar: 120
parameters: []
span:
line_start: 1
line_stop: 1
col_start: 15
col_stop: 18
path: test
content: "console.debug(\"x\");"
span:
line_start: 1
line_stop: 1
col_start: 1
col_stop: 18
path: test
content: "console.debug(\"x\");"
- Console:
function:
Log:

View File

@ -13,13 +13,6 @@ console.error("{}{}", x, y);
console.error("x");
console.debug("{}", x);
console.debug("{}{}", x, y);
console.debug("x");
console.log("{}", x);
console.log("{}{}", x, y);