Merge remote-tracking branch 'origin/testnet3' into feat/hash-symbol-table

This commit is contained in:
evan-schott 2023-09-07 11:09:02 -07:00
commit aceb20b8d5
34 changed files with 898 additions and 368 deletions

View File

@ -102,7 +102,9 @@ jobs:
SCCACHE_DIR: /Users/runner/Library/Caches/Mozilla.sccache
steps:
- name: Xcode Select
uses: devbotsxyz/xcode-select@v1.1.0
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Checkout
uses: actions/checkout@v2

730
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -45,10 +45,12 @@ members = [
]
[workspace.dependencies.snarkvm]
version = "=0.14.5"
git = "https://github.com/AleoHQ/snarkVM.git"
branch = "testnet3"
[workspace.dependencies.snarkvm-console]
version = "=0.14.5"
git = "https://github.com/AleoHQ/snarkVM.git"
branch = "testnet3"
[lib]
path = "leo/lib.rs"

View File

@ -153,6 +153,7 @@ Thank you for helping make Leo better!
<td align="center" valign="top" width="14.28%"><a href="https://github.com/omahs"><img src="https://avatars.githubusercontent.com/u/73983677?v=4?s=100" width="100px;" alt="omahs"/><br /><sub><b>omahs</b></sub></a><br /><a href="https://github.com/AleoHQ/leo/commits?author=omahs" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HarukaMa"><img src="https://avatars.githubusercontent.com/u/861659?v=4?s=100" width="100px;" alt="Haruka"/><br /><sub><b>Haruka</b></sub></a><br /><a href="https://github.com/AleoHQ/leo/issues?q=author%3AHarukaMa" title="Bug reports">🐛</a> <a href="https://github.com/AleoHQ/leo/commits?author=HarukaMa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/swift-mx"><img src="https://avatars.githubusercontent.com/u/80231732?v=4?s=100" width="100px;" alt="swift-mx"/><br /><sub><b>swift-mx</b></sub></a><br /><a href="https://github.com/AleoHQ/leo/commits?author=swift-mx" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dangush"><img src="https://avatars.githubusercontent.com/u/39884512?v=4?s=100" width="100px;" alt="Daniel Gushchyan"/><br /><sub><b>Daniel Gushchyan</b></sub></a><br /><a href="https://github.com/dangush/aleo-lottery" title="Tutorials"></a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/all-contributors/all-contributors-bot"><img src="https://avatars3.githubusercontent.com/u/46843839?v=4?s=100" width="100px;" alt="allcontributors[bot]"/><br /><sub><b>allcontributors[bot]</b></sub></a><br /><a href="https://github.com/AleoHQ/leo/commits?author=allcontributors" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/actions"><img src="https://avatars.githubusercontent.com/u/65916846?v=4?s=100" width="100px;" alt="actions-user[bot]"/><br /><sub><b>actions-user[bot]</b></sub></a><br /><a href="https://github.com/AleoHQ/leo/commits?author=actions-user" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/features/security"><img src="https://avatars.githubusercontent.com/u/27347476?v=4?s=100" width="100px;" alt="dependabot[bot]"/><br /><sub><b>dependabot[bot]</b></sub></a><br /><a href="https://github.com/AleoHQ/leo/commits?author=dependabot" title="Documentation">📖</a></td>

View File

@ -196,6 +196,8 @@ pub enum CoreFunction {
GroupToXCoordinate,
GroupToYCoordinate,
SignatureVerify,
}
impl CoreFunction {
@ -380,6 +382,8 @@ impl CoreFunction {
(sym::group, sym::to_x_coordinate) => Self::GroupToXCoordinate,
(sym::group, sym::to_y_coordinate) => Self::GroupToYCoordinate,
(sym::signature, sym::verify) => Self::SignatureVerify,
_ => return None,
})
}
@ -565,6 +569,8 @@ impl CoreFunction {
Self::GroupToXCoordinate => 1,
Self::GroupToYCoordinate => 1,
Self::SignatureVerify => 3,
}
}
@ -736,7 +742,8 @@ impl CoreFunction {
| CoreFunction::Poseidon8HashToU128
| CoreFunction::Poseidon8HashToScalar
| CoreFunction::GroupToXCoordinate
| CoreFunction::GroupToYCoordinate => false,
| CoreFunction::GroupToYCoordinate
| CoreFunction::SignatureVerify => false,
}
}
}

View File

@ -100,7 +100,7 @@ impl Function {
let output_type = match output.len() {
0 => Type::Unit,
1 => get_output_type(&output[0]),
_ => Type::Tuple(Tuple(output.iter().map(|output| get_output_type(output)).collect())),
_ => Type::Tuple(Tuple(output.iter().map(get_output_type).collect())),
};
Function { annotations, variant, identifier, input, output, output_type, block, finalize, span, id }

View File

@ -40,6 +40,8 @@ pub enum Type {
Mapping(MappingType),
/// The `scalar` type.
Scalar,
/// The `signature` type.
Signature,
/// The `string` type.
String,
/// A static tuple of at least one type.
@ -64,6 +66,7 @@ impl Type {
| (Type::Field, Type::Field)
| (Type::Group, Type::Group)
| (Type::Scalar, Type::Scalar)
| (Type::Signature, Type::Signature)
| (Type::String, Type::String)
| (Type::Unit, Type::Unit) => true,
(Type::Integer(left), Type::Integer(right)) => left.eq(right),
@ -90,6 +93,7 @@ impl fmt::Display for Type {
Type::Integer(ref integer_type) => write!(f, "{integer_type}"),
Type::Mapping(ref mapping_type) => write!(f, "{mapping_type}"),
Type::Scalar => write!(f, "scalar"),
Type::Signature => write!(f, "signature"),
Type::String => write!(f, "string"),
Type::Tuple(ref tuple) => write!(f, "{tuple}"),
Type::Unit => write!(f, "()"),

View File

@ -59,7 +59,7 @@ workspace = true
features = [ "circuit", "console" ]
[dev-dependencies.regex]
version = "1.9.3"
version = "1.9.5"
[dev-dependencies.serde]
version = "1.0.183"

View File

@ -343,6 +343,20 @@ impl ParserContext<'_> {
right: Box::new(args.swap_remove(0)),
id: self.node_builder.next_id(),
}))
} else if let (2, Some(CoreFunction::SignatureVerify)) =
(args.len(), CoreFunction::from_symbols(sym::signature, method.name))
{
Ok(Expression::Access(AccessExpression::AssociatedFunction(AssociatedFunction {
ty: Type::Identifier(Identifier::new(sym::signature, self.node_builder.next_id())),
name: method,
arguments: {
let mut arguments = vec![receiver];
arguments.extend(args);
arguments
},
span,
id: self.node_builder.next_id(),
})))
} else {
// Attempt to parse the method call as a mapping operation.
match (args.len(), CoreFunction::from_symbols(sym::Mapping, method.name)) {

View File

@ -24,6 +24,7 @@ pub(super) const TYPE_TOKENS: &[Token] = &[
Token::Field,
Token::Group,
Token::Scalar,
Token::Signature,
Token::String,
Token::I8,
Token::I16,
@ -66,6 +67,7 @@ impl ParserContext<'_> {
Token::Field => Type::Field,
Token::Group => Type::Group,
Token::Scalar => Type::Scalar,
Token::Signature => Type::Signature,
Token::String => Type::String,
x => Type::Integer(Self::token_to_int_type(x).expect("invalid int type")),
},

View File

@ -412,6 +412,7 @@ impl Token {
"record" => Token::Record,
"return" => Token::Return,
"scalar" => Token::Scalar,
"signature" => Token::Signature,
"self" => Token::SelfLower,
"string" => Token::String,
"struct" => Token::Struct,

View File

@ -114,6 +114,7 @@ mod tests {
return
scalar
self
signature
string
struct
test
@ -169,7 +170,7 @@ mod tests {
assert_eq!(
output,
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address as assert assert_eq assert_neq async bool const else false field finalize for function group i128 i64 i32 i16 i8 if in inline input let mut private program public return scalar self string struct test then transition 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 as assert assert_eq assert_neq async bool const else false field finalize for function group i128 i64 i32 i16 i8 if in inline input let mut private program public return scalar self signature string struct test then transition true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> => _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
/* test */ // "#
);
});

View File

@ -94,6 +94,7 @@ pub enum Token {
Field,
Group,
Scalar,
Signature,
String,
I8,
I16,
@ -178,6 +179,7 @@ pub const KEYWORD_TOKENS: &[Token] = &[
Token::Record,
Token::Return,
Token::SelfLower,
Token::Signature,
Token::Scalar,
Token::String,
Token::Struct,
@ -234,6 +236,7 @@ impl Token {
Token::Record => sym::record,
Token::Return => sym::Return,
Token::Scalar => sym::scalar,
Token::Signature => sym::signature,
Token::SelfLower => sym::SelfLower,
Token::String => sym::string,
Token::Struct => sym::Struct,
@ -321,6 +324,7 @@ impl fmt::Display for Token {
Field => write!(f, "field"),
Group => write!(f, "group"),
Scalar => write!(f, "scalar"),
Signature => write!(f, "signature"),
String => write!(f, "string"),
I8 => write!(f, "i8"),
I16 => write!(f, "i16"),

View File

@ -422,6 +422,18 @@ impl<'a> CodeGenerator<'a> {
.expect("failed to write to string");
(destination_register, instruction)
}
Type::Identifier(Identifier { name: sym::signature, .. }) => {
let mut instruction = " sign.verify".to_string();
let destination_register = get_destination_register();
// Write the arguments and the destination register.
writeln!(
instruction,
" {} {} {} into {destination_register};",
arguments[0], arguments[1], arguments[2]
)
.expect("failed to write to string");
(destination_register, instruction)
}
_ => unreachable!("All core functions should be known at this phase of compilation"),
};
// Add the instruction to the list of instructions.
@ -458,7 +470,7 @@ impl<'a> CodeGenerator<'a> {
Expression::Identifier(identifier) => identifier.name,
_ => unreachable!("Parsing guarantees that a function name is always an identifier."),
};
let return_type = &self.symbol_table.borrow().lookup_fn_symbol(function_name).unwrap().output_type;
let return_type = &self.symbol_table.lookup_fn_symbol(function_name).unwrap().output_type;
match return_type {
Type::Unit => {
call_instruction.push(';');

View File

@ -26,6 +26,7 @@ impl<'a> CodeGenerator<'a> {
| Type::Field
| Type::Group
| Type::Scalar
| Type::Signature
| Type::String
| Type::Integer(..) => format!("{input}"),
Type::Identifier(ident) => format!("{ident}"),

View File

@ -130,7 +130,7 @@ impl ExpressionReconstructor for Flattener<'_> {
elements: first
.elements
.into_iter()
.zip_eq(second.elements.into_iter())
.zip_eq(second.elements)
.map(|(if_true, if_false)| {
// Reconstruct the true case.
let (if_true, stmts) = self.reconstruct_expression(if_true);

View File

@ -175,7 +175,7 @@ impl StatementReconstructor for Flattener<'_> {
_ => unreachable!("Parsing guarantees that `function` is an identifier."),
};
let function = self.symbol_table.borrow().lookup_fn_symbol(function_name).unwrap();
let function = self.symbol_table.lookup_fn_symbol(function_name).unwrap();
match &function.output_type {
// If the function returns a tuple, reconstruct the assignment and add an entry to `self.tuples`.
Type::Tuple(tuple) => {
@ -256,7 +256,7 @@ impl StatementReconstructor for Flattener<'_> {
Expression::Identifier(identifier) => {
// Retrieve the entry in the symbol table for the mapping.
// Note that this unwrap is safe since type checking ensures that the mapping exists.
let variable = self.symbol_table.borrow().lookup_variable(identifier.name).unwrap();
let variable = self.symbol_table.lookup_variable(identifier.name).unwrap();
match &variable.type_ {
Type::Mapping(mapping_type) => &*mapping_type.value,
_ => unreachable!("Type checking guarantee that `arguments[0]` is a mapping."),
@ -292,7 +292,7 @@ impl StatementReconstructor for Flattener<'_> {
_ => unreachable!("Parsing guarantees that `function` is an identifier."),
};
let function = self.symbol_table.borrow().lookup_fn_symbol(function_name).unwrap();
let function = self.symbol_table.lookup_fn_symbol(function_name).unwrap();
let output_type = match &function.output_type {
Type::Tuple(tuple) => tuple.clone(),
@ -322,8 +322,7 @@ impl StatementReconstructor for Flattener<'_> {
}
// If the lhs is a tuple and the rhs is a tuple, create a new assign statement for each tuple element.
(Expression::Tuple(lhs_tuple), Expression::Tuple(rhs_tuple)) => {
statements.extend(lhs_tuple.elements.into_iter().zip(rhs_tuple.elements.into_iter()).map(
|(lhs, rhs)| {
statements.extend(lhs_tuple.elements.into_iter().zip(rhs_tuple.elements).map(|(lhs, rhs)| {
let identifier = match &lhs {
Expression::Identifier(identifier) => identifier,
_ => unreachable!("Type checking guarantees that `lhs` is an identifier."),
@ -335,8 +334,7 @@ impl StatementReconstructor for Flattener<'_> {
span: Default::default(),
id: self.node_builder.next_id(),
}))
},
));
}));
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
}
// If the lhs is a tuple and the rhs is an identifier that is a tuple, create a new assign statement for each tuple element.
@ -347,7 +345,7 @@ impl StatementReconstructor for Flattener<'_> {
// Note that the `unwrap` is safe since the match arm checks that the entry exists.
let rhs_tuple = self.tuples.get(&identifier.name).unwrap().clone();
// Create a new assign statement for each tuple element.
for (lhs, rhs) in lhs_tuple.elements.into_iter().zip(rhs_tuple.elements.into_iter()) {
for (lhs, rhs) in lhs_tuple.elements.into_iter().zip(rhs_tuple.elements) {
let identifier = match &lhs {
Expression::Identifier(identifier) => identifier,
_ => unreachable!("Type checking guarantees that `lhs` is an identifier."),

View File

@ -59,7 +59,7 @@ impl ExpressionReconstructor for FunctionInliner<'_> {
.input
.iter()
.map(|input| input.identifier().name)
.zip_eq(input.arguments.into_iter())
.zip_eq(input.arguments)
.collect::<IndexMap<_, _>>();
// Initializer `self.assignment_renamer` with the function parameters.

View File

@ -38,7 +38,7 @@ impl StatementReconstructor for FunctionInliner<'_> {
match (input.place, value) {
// If the function call produces a tuple, we need to segment the tuple into multiple assignment statements.
(Expression::Tuple(left), Expression::Tuple(right)) if left.elements.len() == right.elements.len() => {
statements.extend(left.elements.into_iter().zip(right.elements.into_iter()).map(|(lhs, rhs)| {
statements.extend(left.elements.into_iter().zip(right.elements).map(|(lhs, rhs)| {
Statement::Assign(Box::new(AssignStatement {
place: lhs,
value: rhs,

View File

@ -40,7 +40,6 @@ use leo_ast::{
use leo_span::{sym, Symbol};
use indexmap::IndexMap;
use std::borrow::Borrow;
impl ExpressionConsumer for StaticSingleAssigner<'_> {
type Output = (Expression, Vec<Statement>);
@ -212,7 +211,7 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
// Lookup the struct definition.
// Note that type checking guarantees that the correct struct definition exists.
let struct_definition: &Struct = self.symbol_table.borrow().lookup_struct(input.name.name).unwrap();
let struct_definition: &Struct = self.symbol_table.lookup_struct(input.name.name).unwrap();
// Initialize the list of reordered members.
let mut reordered_members = Vec::with_capacity(members.len());

View File

@ -520,16 +520,14 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
fn visit_cast(&mut self, input: &'a CastExpression, expected: &Self::AdditionalInput) -> Self::Output {
// Check that the target type of the cast expression is a castable type.
let target_type = Some(input.type_.clone());
self.assert_castable_type(&target_type, input.span());
self.assert_castable_type(&Some(input.type_.clone()), input.span());
// Check that the expression type is a primitive type.
let expression_type = self.visit_expression(&input.expression, &None);
self.assert_castable_type(&expression_type, input.expression.span());
// Check that the expected type matches the target type.
// Note that this unwrap is safe since target_type is always `Some`.
Some(self.assert_and_return_type(target_type.unwrap(), expected, input.span()))
Some(self.assert_and_return_type(input.type_.clone(), expected, input.span()))
}
fn visit_struct_init(&mut self, input: &'a StructExpression, additional: &Self::AdditionalInput) -> Self::Output {

View File

@ -59,6 +59,8 @@ const GROUP_TYPE: Type = Type::Group;
const SCALAR_TYPE: Type = Type::Scalar;
const SIGNATURE_TYPE: Type = Type::Signature;
const INT_TYPES: [Type; 10] = [
Type::Integer(IntegerType::I8),
Type::Integer(IntegerType::I16),
@ -173,7 +175,6 @@ impl<'a> TypeChecker<'a> {
self.emit_err(TypeCheckerError::type_should_be(actual.clone(), expected, span));
}
}
actual
}
@ -182,6 +183,11 @@ impl<'a> TypeChecker<'a> {
self.check_type(|actual: &Type| actual.eq_flat(expected), expected.to_string(), actual, span)
}
/// Emits an error to the error handler if the given type is not an address.
pub(crate) fn assert_address_type(&self, type_: &Option<Type>, span: Span) {
self.check_type(|type_: &Type| ADDRESS_TYPE.eq(type_), ADDRESS_TYPE.to_string(), type_, span)
}
/// Emits an error to the handler if the given type is not a boolean.
pub(crate) fn assert_bool_type(&self, type_: &Option<Type>, span: Span) {
self.check_type(|type_: &Type| BOOLEAN_TYPE.eq(type_), BOOLEAN_TYPE.to_string(), type_, span)
@ -202,6 +208,11 @@ impl<'a> TypeChecker<'a> {
self.check_type(|type_: &Type| SCALAR_TYPE.eq(type_), SCALAR_TYPE.to_string(), type_, span)
}
/// Emits an error to the handler if the given type is not a signature.
pub(crate) fn assert_signature_type(&self, type_: &Option<Type>, span: Span) {
self.check_type(|type_: &Type| SIGNATURE_TYPE.eq(type_), SIGNATURE_TYPE.to_string(), type_, span)
}
/// Emits an error to the handler if the given type is not an integer.
pub(crate) fn assert_int_type(&self, type_: &Option<Type>, span: Span) {
self.check_type(|type_: &Type| INT_TYPES.contains(type_), types_to_string(&INT_TYPES), type_, span)
@ -917,6 +928,14 @@ impl<'a> TypeChecker<'a> {
CoreFunction::ChaChaRandU32 => Some(Type::Integer(IntegerType::U32)),
CoreFunction::ChaChaRandU64 => Some(Type::Integer(IntegerType::U64)),
CoreFunction::ChaChaRandU128 => Some(Type::Integer(IntegerType::U128)),
CoreFunction::SignatureVerify => {
// Check that the first argument is a signature.
self.assert_signature_type(&arguments[0].0, arguments[0].1);
// Check that the second argument is an address.
self.assert_address_type(&arguments[1].0, arguments[1].1);
// Return a boolean.
Some(Type::Boolean)
}
}
}

View File

@ -195,6 +195,7 @@ symbols! {
set,
to_x_coordinate,
to_y_coordinate,
verify,
// types
address,
@ -208,6 +209,7 @@ symbols! {
i128,
record,
scalar,
signature,
string,
Struct: "struct",
u8,

View File

@ -0,0 +1,12 @@
---
namespace: Compile
expectation: Pass
outputs:
- - initial_ast: 66326647c8591d4479e5622bc50d2fffb7fcc9791925a7ab7018617a59b693a4
unrolled_ast: 66326647c8591d4479e5622bc50d2fffb7fcc9791925a7ab7018617a59b693a4
ssa_ast: 76f4f34b1e014012ba3ecc136b58787ed41de71f5ff83565f825258b9e8ea76f
flattened_ast: b0658ac6a7f5033380851c648f130884de04fde4bef415fa015e4d664aabb427
inlined_ast: b0658ac6a7f5033380851c648f130884de04fde4bef415fa015e4d664aabb427
dce_ast: b0658ac6a7f5033380851c648f130884de04fde4bef415fa015e4d664aabb427
bytecode: 87b34bffefde3c2b9e23ce08528737a4ef06a28ee9120c02d26ee41989f24cd2
warnings: ""

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372007]: Expected one type from `signature`, but got `address`\n --> compiler-test:11:45\n |\n 11 | let first: bool = signature::verify(a, s, v);\n | ^\nError [ETYC0372007]: Expected one type from `address`, but got `signature`\n --> compiler-test:11:48\n |\n 11 | let first: bool = signature::verify(a, s, v);\n | ^\nError [ETYC0372007]: Expected one type from `address`, but got `u8`\n --> compiler-test:12:37\n |\n 12 | let second: bool = s.verify(1u8, v);\n | ^^^\nError [ETYC0372007]: Expected one type from `signature`, but got `address`\n --> compiler-test:17:45\n |\n 17 | let first: bool = signature::verify(a, v, s);\n | ^\nError [ETYC0372007]: Expected one type from `address`, but got `foo`\n --> compiler-test:17:48\n |\n 17 | let first: bool = signature::verify(a, v, s);\n | ^\nError [ETYC0372007]: Expected one type from `address`, but got `foo`\n --> compiler-test:18:37\n |\n 18 | let second: bool = s.verify(v, a);\n | ^\n"

View File

@ -3,7 +3,7 @@ namespace: ParseExpression
expectation: Fail
outputs:
- "did not consume all input: 'aas' @ 1:5-8\n'u8' @ 1:9-11\n"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '{'\n --> test:1:10\n |\n 1 | 1u128 as { foo: u8 }\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '{'\n --> test:1:10\n |\n 1 | 1u128 as { foo: u8 }\n | ^"
- "did not consume all input: ';' @ 1:14-15\n"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found 'bar'\n --> test:1:8\n |\n 1 | 1u8 as bar;\n | ^^^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found 'bar'\n --> test:1:8\n |\n 1 | 1u8 as bar;\n | ^^^"
- "did not consume all input: 'asu8' @ 1:5-9\n"

View File

@ -25,22 +25,22 @@ outputs:
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ','\n --> test:1:10\n |\n 1 | let (x,y,,) = ();\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ','\n --> test:1:6\n |\n 1 | let (,x,y) = ();\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ','\n --> test:1:8\n |\n 1 | let (x,,y) = ();\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8; (2,,)] = [[0,0], [0,0]];\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found 'constant'\n --> test:1:8\n |\n 1 | let x: constant = expr;\n | ^^^^^^^^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8; (2,,)] = [[0,0], [0,0]];\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found 'constant'\n --> test:1:8\n |\n 1 | let x: constant = expr;\n | ^^^^^^^^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found 'constant'\n --> test:1:1\n |\n 1 | constant x: let = expr;\n | ^^^^^^^^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found '<eof>'\n --> test:1:1\n |\n 1 | let\n | ^^^"
- "Error [EPAR0370005]: expected : -- found '<eof>'\n --> test:1:5\n |\n 1 | let x\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '<eof>'\n --> test:1:6\n |\n 1 | let x:\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '<eof>'\n --> test:1:6\n |\n 1 | let x:\n | ^"
- "Error [EPAR0370005]: expected : -- found '='\n --> test:1:7\n |\n 1 | let x = (a, y]);\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found '='\n --> test:1:5\n |\n 1 | let = 1u8;\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ';'\n --> test:1:4\n |\n 1 | let;\n | ^"
- "Error [EPAR0370005]: expected : -- found '1'\n --> test:1:7\n |\n 1 | let x 1u8;\n | ^"
- "Error [EPAR0370005]: expected = -- found ';'\n --> test:1:10\n |\n 1 | let x: u8;\n | ^"
- "Error [EPAR0370005]: expected = -- found '<eof>'\n --> test:1:8\n |\n 1 | let x: u8\n | ^^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '='\n --> test:1:8\n |\n 1 | let x: = 1;\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8] = 1;\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8;\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8; 1u8] = [1,\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '='\n --> test:1:8\n |\n 1 | let x: = 1;\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8] = 1;\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8;\n | ^"
- "Error [EPAR0370005]: expected 'address', 'bool', 'field', 'group', 'scalar', 'signature', 'string', 'i8', 'i16', 'i32', 'i64', 'i128', 'u8', 'u16', 'u32', 'u64', 'u128' -- found '['\n --> test:1:8\n |\n 1 | let x: [u8; 1u8] = [1,\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ']'\n --> test:1:15\n |\n 1 | let dbg: u8 = ];\n | ^"
- "Error [EPAR0370016]: Could not lex the following content: `🦀:`.\n"
- "Error [EPAR0370005]: expected : -- found '='\n --> test:1:9\n |\n 1 | let (x) = ...;\n | ^"

View File

@ -0,0 +1,259 @@
---
namespace: Parse
expectation: Pass
outputs:
- imports: {}
program_scopes:
"{\"name\":\"test\",\"network\":\"\\\"{\\\\\\\"id\\\\\\\":\\\\\\\"1\\\\\\\",\\\\\\\"name\\\\\\\":\\\\\\\"aleo\\\\\\\",\\\\\\\"span\\\\\\\":\\\\\\\"{\\\\\\\\\\\\\\\"lo\\\\\\\\\\\\\\\":15,\\\\\\\\\\\\\\\"hi\\\\\\\\\\\\\\\":19}\\\\\\\"}\\\"\"}":
program_id: "{\"name\":\"test\",\"network\":\"\\\"{\\\\\\\"id\\\\\\\":\\\\\\\"1\\\\\\\",\\\\\\\"name\\\\\\\":\\\\\\\"aleo\\\\\\\",\\\\\\\"span\\\\\\\":\\\\\\\"{\\\\\\\\\\\\\\\"lo\\\\\\\\\\\\\\\":15,\\\\\\\\\\\\\\\"hi\\\\\\\\\\\\\\\":19}\\\\\\\"}\\\"\"}"
structs: {}
mappings: {}
functions:
baz:
annotations: []
variant: Transition
identifier: "{\"id\":\"2\",\"name\":\"baz\",\"span\":\"{\\\"lo\\\":37,\\\"hi\\\":40}\"}"
input:
- Internal:
identifier: "{\"id\":\"3\",\"name\":\"s\",\"span\":\"{\\\"lo\\\":41,\\\"hi\\\":42}\"}"
mode: None
type_: Signature
span:
lo: 41
hi: 42
id: 4
- Internal:
identifier: "{\"id\":\"5\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":55,\\\"hi\\\":56}\"}"
mode: None
type_: Address
span:
lo: 55
hi: 56
id: 6
- Internal:
identifier: "{\"id\":\"7\",\"name\":\"v\",\"span\":\"{\\\"lo\\\":67,\\\"hi\\\":68}\"}"
mode: None
type_:
Identifier: "{\"id\":\"8\",\"name\":\"value\",\"span\":\"{\\\"lo\\\":70,\\\"hi\\\":75}\"}"
span:
lo: 67
hi: 68
id: 9
output: []
output_type: Unit
block:
statements:
- Definition:
declaration_type: Let
place:
Identifier: "{\"id\":\"10\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":91,\\\"hi\\\":92}\"}"
type_: Boolean
value:
Access:
AssociatedFunction:
ty:
Identifier: "{\"id\":\"11\",\"name\":\"signature\",\"span\":\"{\\\"lo\\\":101,\\\"hi\\\":110}\"}"
name: "{\"id\":\"12\",\"name\":\"verify\",\"span\":\"{\\\"lo\\\":112,\\\"hi\\\":118}\"}"
arguments:
- Identifier: "{\"id\":\"13\",\"name\":\"s\",\"span\":\"{\\\"lo\\\":119,\\\"hi\\\":120}\"}"
- Identifier: "{\"id\":\"14\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":122,\\\"hi\\\":123}\"}"
- Identifier: "{\"id\":\"15\",\"name\":\"v\",\"span\":\"{\\\"lo\\\":125,\\\"hi\\\":126}\"}"
span:
lo: 101
hi: 127
id: 16
span:
lo: 87
hi: 127
id: 17
- Definition:
declaration_type: Let
place:
Identifier: "{\"id\":\"18\",\"name\":\"b\",\"span\":\"{\\\"lo\\\":141,\\\"hi\\\":142}\"}"
type_: Boolean
value:
Access:
AssociatedFunction:
ty:
Identifier: "{\"id\":\"23\",\"name\":\"signature\",\"span\":\"{\\\"lo\\\":0,\\\"hi\\\":0}\"}"
name: "{\"id\":\"20\",\"name\":\"verify\",\"span\":\"{\\\"lo\\\":153,\\\"hi\\\":159}\"}"
arguments:
- Identifier: "{\"id\":\"19\",\"name\":\"s\",\"span\":\"{\\\"lo\\\":151,\\\"hi\\\":152}\"}"
- Identifier: "{\"id\":\"21\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":160,\\\"hi\\\":161}\"}"
- Identifier: "{\"id\":\"22\",\"name\":\"v\",\"span\":\"{\\\"lo\\\":163,\\\"hi\\\":164}\"}"
span:
lo: 151
hi: 165
id: 24
span:
lo: 137
hi: 165
id: 25
- Assert:
variant:
AssertEq:
- Identifier: "{\"id\":\"26\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":185,\\\"hi\\\":186}\"}"
- Identifier: "{\"id\":\"27\",\"name\":\"b\",\"span\":\"{\\\"lo\\\":188,\\\"hi\\\":189}\"}"
span:
lo: 175
hi: 184
id: 28
span:
lo: 77
hi: 197
id: 29
finalize: ~
span:
lo: 26
hi: 197
id: 30
bar:
annotations: []
variant: Transition
identifier: "{\"id\":\"31\",\"name\":\"bar\",\"span\":\"{\\\"lo\\\":214,\\\"hi\\\":217}\"}"
input:
- Internal:
identifier: "{\"id\":\"32\",\"name\":\"x\",\"span\":\"{\\\"lo\\\":218,\\\"hi\\\":219}\"}"
mode: None
type_:
Integer: U8
span:
lo: 218
hi: 219
id: 33
output:
- Internal:
mode: None
type_:
Integer: U8
span:
lo: 228
hi: 230
id: 34
output_type:
Integer: U8
block:
statements:
- Definition:
declaration_type: Let
place:
Identifier: "{\"id\":\"35\",\"name\":\"signature\",\"span\":\"{\\\"lo\\\":245,\\\"hi\\\":254}\"}"
type_:
Integer: U8
value:
Binary:
left:
Literal:
Integer:
- U8
- "1"
- span:
lo: 261
hi: 264
- 36
right:
Identifier: "{\"id\":\"37\",\"name\":\"x\",\"span\":\"{\\\"lo\\\":267,\\\"hi\\\":268}\"}"
op: Add
span:
lo: 261
hi: 268
id: 38
span:
lo: 241
hi: 268
id: 39
- Return:
expression:
Identifier: "{\"id\":\"40\",\"name\":\"signature\",\"span\":\"{\\\"lo\\\":285,\\\"hi\\\":294}\"}"
finalize_arguments: ~
span:
lo: 278
hi: 295
id: 41
span:
lo: 231
hi: 301
id: 42
finalize: ~
span:
lo: 203
hi: 301
id: 43
bax:
annotations: []
variant: Transition
identifier: "{\"id\":\"44\",\"name\":\"bax\",\"span\":\"{\\\"lo\\\":317,\\\"hi\\\":320}\"}"
input:
- Internal:
identifier: "{\"id\":\"45\",\"name\":\"s\",\"span\":\"{\\\"lo\\\":321,\\\"hi\\\":322}\"}"
mode: None
type_: Signature
span:
lo: 321
hi: 322
id: 46
- Internal:
identifier: "{\"id\":\"47\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":335,\\\"hi\\\":336}\"}"
mode: None
type_: Address
span:
lo: 335
hi: 336
id: 48
- Internal:
identifier: "{\"id\":\"49\",\"name\":\"v\",\"span\":\"{\\\"lo\\\":347,\\\"hi\\\":348}\"}"
mode: None
type_:
Identifier: "{\"id\":\"50\",\"name\":\"value\",\"span\":\"{\\\"lo\\\":350,\\\"hi\\\":355}\"}"
span:
lo: 347
hi: 348
id: 51
output: []
output_type: Unit
block:
statements:
- Definition:
declaration_type: Let
place:
Identifier: "{\"id\":\"52\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":370,\\\"hi\\\":371}\"}"
type_: Boolean
value:
Access:
AssociatedFunction:
ty:
Identifier: "{\"id\":\"53\",\"name\":\"signature\",\"span\":\"{\\\"lo\\\":380,\\\"hi\\\":389}\"}"
name: "{\"id\":\"54\",\"name\":\"sign\",\"span\":\"{\\\"lo\\\":391,\\\"hi\\\":395}\"}"
arguments:
- Identifier: "{\"id\":\"55\",\"name\":\"s\",\"span\":\"{\\\"lo\\\":396,\\\"hi\\\":397}\"}"
- Identifier: "{\"id\":\"56\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":399,\\\"hi\\\":400}\"}"
- Identifier: "{\"id\":\"57\",\"name\":\"v\",\"span\":\"{\\\"lo\\\":402,\\\"hi\\\":403}\"}"
span:
lo: 380
hi: 404
id: 58
span:
lo: 366
hi: 404
id: 59
- Assert:
variant:
AssertEq:
- Identifier: "{\"id\":\"60\",\"name\":\"a\",\"span\":\"{\\\"lo\\\":423,\\\"hi\\\":424}\"}"
- Identifier: "{\"id\":\"61\",\"name\":\"b\",\"span\":\"{\\\"lo\\\":426,\\\"hi\\\":427}\"}"
span:
lo: 413
hi: 422
id: 62
span:
lo: 357
hi: 434
id: 63
finalize: ~
span:
lo: 306
hi: 434
id: 64
span:
lo: 2
hi: 436

View File

@ -0,0 +1,5 @@
---
namespace: Parse
expectation: Fail
outputs:
- "Error [EPAR0370021]: The type of `signature` has no associated function `verify` that takes 3 argument(s).\n --> test:5:23\n |\n 5 | let a: bool = signature.verify(s, a, v);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [EPAR0370005]: expected ) -- found ','\n --> test:6:17\n |\n 6 | assert(a, b);\n | ^"

View File

@ -45,7 +45,7 @@ features = [ "preserve_order" ]
version = "0.8"
[dependencies.walkdir]
version = "2.3"
version = "2.4"
[dependencies.regex]
version = "1.9"

View File

@ -0,0 +1,24 @@
/*
namespace: Compile
expectation: Pass
*/
program test.aleo {
struct foo {
a: u8,
b: scalar
}
transition verify_field(s: signature, a: address, v: field) {
let first: bool = signature::verify(s, a, v);
let second: bool = s.verify(a, v);
assert_eq(first, second);
}
transition verify_foo(s: signature, a: address, v: foo) {
let first: bool = signature::verify(s, a, v);
let second: bool = s.verify(a, v);
assert_eq(first, second);
}
}

View File

@ -0,0 +1,24 @@
/*
namespace: Compile
expectation: Fail
*/
program test.aleo {
struct foo {
a: u8,
b: scalar
}
transition verify_field(s: signature, a: address, v: field) {
let first: bool = signature::verify(a, s, v);
let second: bool = s.verify(1u8, v);
assert_eq(first, second);
}
transition verify_foo(s: signature, a: address, v: foo) {
let first: bool = signature::verify(a, v, s);
let second: bool = s.verify(v, a);
assert_eq(first, second);
}
}

View File

@ -0,0 +1,22 @@
/*
namespace: Parse
expectation: Pass
*/
program test.aleo {
transition baz(s: signature, a: address, v: value) {
let a: bool = signature::verify(s, a, v);
let b: bool = s.verify(a, v);
assert_eq(a, b);
}
transition bar(x: u8) -> u8 {
let signature: u8 = 1u8 + x;
return signature;
}
transition bax(s: signature, a: address, v: value) {
let a: bool = signature::sign(s, a, v);
assert_eq(a, b);
}
}

View File

@ -0,0 +1,24 @@
/*
namespace: Parse
expectation: Fail
*/
program test.aleo {
transition baz(s: signature, a: address, v: value) {
let a: bool = signature.verify(s, a, v);
assert(a, b);
}
transition bar(s: signature, a: address, v: value) {
let b: bool = s.verify(a, a, v);
assert_eq(a, b);
}
transition foo(signature: field) -> u8 {
return 0u8;
}
transition signature(foo: field) -> u8 {
return 0u8;
}
}