Merge pull request #2088 from AleoHQ/feat/async-on-finalize-statement

Requires async keyword before finalize statement.
This commit is contained in:
Collin Chin 2022-09-21 14:41:56 -07:00 committed by GitHub
commit 9b9c494932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 89 additions and 63 deletions

View File

@ -41,7 +41,9 @@ impl ParserContext<'_> {
pub(crate) fn parse_statement(&mut self) -> Result<Statement> {
match &self.token.token {
Token::Return => Ok(Statement::Return(self.parse_return_statement()?)),
Token::Finalize => Ok(Statement::Finalize(self.parse_finalize_statement()?)),
Token::Async => Ok(Statement::Finalize(self.parse_finalize_statement()?)),
// If a finalize token is found without a preceding async token, return an error.
Token::Finalize => Err(ParserError::finalize_without_async(self.token.span).into()),
Token::Increment => Ok(Statement::Increment(self.parse_increment_statement()?)),
Token::Decrement => Ok(Statement::Decrement(self.parse_decrement_statement()?)),
Token::If => Ok(Statement::Conditional(self.parse_conditional_statement()?)),
@ -122,6 +124,7 @@ impl ParserContext<'_> {
/// Returns a [`FinalizeStatement`] AST node if the next tokens represent a finalize statement.
fn parse_finalize_statement(&mut self) -> Result<FinalizeStatement> {
self.expect(&Token::Async)?;
let start = self.expect(&Token::Finalize)?;
let (arguments, _, span) = self.parse_paren_comma_list(|p| p.parse_expression().map(Some))?;
self.expect(&Token::Semicolon)?;

View File

@ -394,6 +394,7 @@ impl Token {
match &*identifier {
x if x.starts_with("aleo1") => Token::AddressLit(identifier),
"address" => Token::Address,
"async" => Token::Async,
"bool" => Token::Bool,
"circuit" => Token::Circuit,
"console" => Token::Console,

View File

@ -83,6 +83,7 @@ mod tests {
test_ident
12345
address
async
bool
const
else
@ -157,7 +158,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 finalize for function group i128 i64 i32 i16 i8 if in input let mut return scalar self 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 async bool const else false field finalize for function group i128 i64 i32 i16 i8 if in input let mut return scalar self string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> => _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
/* test */ // "#
);
});

View File

@ -108,6 +108,7 @@ pub enum Token {
Record,
// Regular Keywords
Async,
Circuit,
Console,
// Const variable and a const function.
@ -143,6 +144,7 @@ pub enum Token {
/// because true and false are also boolean literals, which are different tokens from keywords
pub const KEYWORD_TOKENS: &[Token] = &[
Token::Address,
Token::Async,
Token::Bool,
Token::Circuit,
Token::Console,
@ -192,6 +194,7 @@ impl Token {
pub fn keyword_to_symbol(&self) -> Option<Symbol> {
Some(match self {
Token::Address => sym::address,
Token::Async => sym::Async,
Token::Bool => sym::bool,
Token::Circuit => sym::circuit,
Token::Console => sym::console,
@ -319,6 +322,7 @@ impl fmt::Display for Token {
U128 => write!(f, "u128"),
Record => write!(f, "record"),
Async => write!(f, "async"),
Circuit => write!(f, "circuit"),
Console => write!(f, "console"),
Const => write!(f, "const"),

View File

@ -181,6 +181,7 @@ symbols! {
// general keywords
AlwaysConst,
assert,
Async: "async",
caller,
circuit,
Class: "class",

View File

@ -260,4 +260,11 @@ create_messages!(
msg: "Illegal spacing in the annotation declaration.",
help: Some("Remove whitespace between the `@` symbol and the identifier.".to_string()),
}
@formatted
finalize_without_async {
args: (),
msg: "A finalize statement must be preceded by the `async` keyword.",
help: Some("Add the `async` keyword before the `finalize` keyword.".to_string()),
}
);

View File

@ -28,7 +28,7 @@ function deposit(token: Token, amount: u64) -> Token {
let hash: field = BHP256::hash(token.owner);
finalize(hash, amount);
async finalize(hash, amount);
return remaining;
}
@ -50,7 +50,7 @@ function withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> T
amount: total,
};
finalize(hash, amount);
async finalize(hash, amount);
return token;
}

View File

@ -17,7 +17,7 @@ record token {
@program
function mint_public(public receiver: address, public amount: u64) {
// Mint the tokens publicly by invoking the computation on-chain.
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public(public receiver: address, public amount: u64) {
@ -41,7 +41,7 @@ function mint_private(receiver: address, amount: u64) -> token {
@program
function transfer_public(public receiver: address, public amount: u64) {
// Transfer the tokens publicly, by invoking the computation on-chain.
finalize(self.caller, receiver, amount);
async finalize(self.caller, receiver, amount);
}
finalize transfer_public(public sender: address, public receiver: address, public amount: u64) {
@ -98,7 +98,7 @@ function transfer_private_to_public(sender: token, public receiver: address, pub
};
// Increment the token amount publicly for the token receiver.
finalize(receiver, amount);
async finalize(receiver, amount);
// Output the sender's change record.
return remaining;
@ -123,7 +123,7 @@ function transfer_public_to_private(public receiver: address, public amount: u64
};
// Decrement the token amount of the caller publicly.
finalize(self.caller, amount);
async finalize(self.caller, amount);
// Output the receiver's record.
return transferred;

View File

@ -42,7 +42,7 @@ function propose(public info: ProposalInfo) -> Proposal {
let id: field = BHP256::hash(info.title);
// Finalize the proposal id.
finalize(id);
async finalize(id);
// Return a new record for the proposal.
return Proposal {
@ -64,7 +64,7 @@ function new_ticket(
public voter: address,
) -> Ticket {
// Finalize the proposal id for the ticket.
finalize(pid);
async finalize(pid);
return Ticket {
owner: voter,
@ -80,7 +80,7 @@ finalize new_ticket(public pid: field) {
// Vote to agree with a proposal.
@program
function agree(ticket: Ticket) {// Privately cast the vote.
finalize(ticket.pid);
async finalize(ticket.pid);
}
finalize agree(public pid: field) {// Publicly increment the number of agree votes.
increment(agree_votes, pid, 1u64);
@ -89,7 +89,7 @@ finalize agree(public pid: field) {// Publicly increment the number of agree vot
// Vote to disagree with a proposal.
@program
function disagree(ticket: Ticket) {// Privately cast the vote.
finalize(ticket.pid);
async finalize(ticket.pid);
}
finalize disagree(pid: field) {// Publicly increment the number of disagree votes.
increment(disagree_votes, pid, 1u64);

View File

@ -4,7 +4,7 @@ expectation: Fail
*/
function foo(a: u8, b: u8) -> u8 {
finalize(a, b);
async finalize(a, b);
return a + b;
}
@ -18,7 +18,7 @@ finalize bar(a: u8, b: u8) -> u8 {
function mint_public(receiver: address, amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public(receiver: address, amount: u64) {

View File

@ -7,7 +7,7 @@ mapping amounts: address => u128;
@program
function decrease_self(amount: u128) {
finalize(self.caller, amount);
async finalize(self.caller, amount);
}
finalize decrease_self(addr: address, amount: u128) {

View File

@ -14,7 +14,7 @@ mapping tokens: address => Token;
@program
function decrease_self(amount: u128) {
finalize(self.caller, amount);
async finalize(self.caller, amount);
}
finalize decrease_self(addr: address, amount: u128) {

View File

@ -6,7 +6,7 @@ expectation: Fail
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public (public receiver: address, public amount: u64) {}

View File

@ -8,7 +8,7 @@ mapping values: u8 => u8;
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public (public receiver: address, public amount: u64) {
@ -17,14 +17,14 @@ finalize mint_public (public receiver: address, public amount: u64) {
@program
function public_adder(public a: u8, public b: u8) {
finalize(a, b);
async finalize(a, b);
} finalize public_adder(a: u8, b: u8) -> public u8 {
return a + b;
}
@program
function finalize_no_params() {
finalize();
async finalize();
}
finalize finalize_no_params() {

View File

@ -7,7 +7,7 @@ mapping account: address => u64;
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public (public receiver: address, constant amount: u64) -> constant u64 {
@ -16,7 +16,7 @@ finalize mint_public (public receiver: address, constant amount: u64) -> constan
@program
function mint_public2(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public2(public receiver: address, amount: u64) -> u64 {

View File

@ -7,7 +7,7 @@ mapping account: address => u64;
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public(public receiver: address, public amount: u64) -> u64 {

View File

@ -8,7 +8,7 @@ mapping account: address => u64;
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_public (public receiver: address, public amount: u64) -> u64 {

View File

@ -8,7 +8,7 @@ mapping values: u8 => u8;
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount);
async finalize(receiver, amount);
}
finalize mint_private (public receiver: address, public amount: u64) {

View File

@ -8,7 +8,7 @@ mapping account: address => u64;
@program
function mint_public(public receiver: address, public amount: u64) {
finalize(receiver, amount, amount);
async finalize(receiver, amount, amount);
}
finalize mint_public (public receiver: address, public amount: u64) {

View File

@ -7,7 +7,7 @@ mapping amounts: address => u128;
@program
function increase_self(amount: u128) {
finalize(self.caller, amount);
async finalize(self.caller, amount);
}
finalize increase_self(addr: address, amount: u128) {

View File

@ -14,7 +14,7 @@ mapping tokens: address => Token;
@program
function increase_self(amount: u128) {
finalize(self.caller, amount);
async finalize(self.caller, amount);
}
finalize increase_self(addr: address, amount: u128) {

View File

@ -22,7 +22,7 @@ finalize read_in_finalize(public addr: address) -> public u128 {
}
function write_in_finalize(public addr: address, public amount: u128) {
finalize(addr, amount);
async finalize(addr, amount);
}
finalize write_in_finalize(public: addr: address, public amount: u128) {

View File

@ -5,7 +5,7 @@ expectation: Pass
@program
function matches(addr: address) -> bool {
finalize(self.caller);
async finalize(self.caller);
return self.caller == addr;
} finalize matches(addr: address) -> bool {
return addr == self.caller;

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372036]: Cannot use a `finalize` statement without a `finalize` block.\n --> compiler-test:4:5\n |\n 4 | finalize(a, b);\n | ^^^^^^^^^^^^^^\nError [ETYC0372044]: Function must contain a `finalize` statement on all execution paths.\n --> compiler-test:8:1\n |\n 8 | function bar(a: u8, b: u8) -> u8 {\n 9 | return a + b;\n 10 | }\n | ^\nError [ETYC0372032]: Only program functions can have a `finalize` block.\n --> compiler-test:12:1\n |\n 12 | finalize bar(a: u8, b: u8) -> u8 {\n 13 | return a + b;\n 14 | }\n | ^\n |\n = Remove the `finalize` block or add a `@program` annotation to the function.\nError [ETYC0372032]: Only program functions can have a `finalize` block.\n --> compiler-test:21:1\n |\n 21 | finalize mint_public(receiver: address, amount: u64) {\n 22 | increment(account, receiver, amount);\n 23 | }\n | ^\n |\n = Remove the `finalize` block or add a `@program` annotation to the function.\nError [ETYC0372005]: Unknown variable `account`\n --> compiler-test:22:15\n |\n 22 | increment(account, receiver, amount);\n | ^^^^^^^\nError [ETYC0372004]: Could not determine the type of `account`\n --> compiler-test:22:15\n |\n 22 | increment(account, receiver, amount);\n | ^^^^^^^\n"
- "Error [ETYC0372036]: Cannot use a `finalize` statement without a `finalize` block.\n --> compiler-test:4:11\n |\n 4 | async finalize(a, b);\n | ^^^^^^^^^^^^^^\nError [ETYC0372044]: Function must contain a `finalize` statement on all execution paths.\n --> compiler-test:8:1\n |\n 8 | function bar(a: u8, b: u8) -> u8 {\n 9 | return a + b;\n 10 | }\n | ^\nError [ETYC0372032]: Only program functions can have a `finalize` block.\n --> compiler-test:12:1\n |\n 12 | finalize bar(a: u8, b: u8) -> u8 {\n 13 | return a + b;\n 14 | }\n | ^\n |\n = Remove the `finalize` block or add a `@program` annotation to the function.\nError [ETYC0372032]: Only program functions can have a `finalize` block.\n --> compiler-test:21:1\n |\n 21 | finalize mint_public(receiver: address, amount: u64) {\n 22 | increment(account, receiver, amount);\n 23 | }\n | ^\n |\n = Remove the `finalize` block or add a `@program` annotation to the function.\nError [ETYC0372005]: Unknown variable `account`\n --> compiler-test:22:15\n |\n 22 | increment(account, receiver, amount);\n | ^^^^^^^\nError [ETYC0372004]: Could not determine the type of `account`\n --> compiler-test:22:15\n |\n 22 | increment(account, receiver, amount);\n | ^^^^^^^\n"

View File

@ -4,7 +4,7 @@ expectation: Pass
outputs:
- output:
- initial_input_ast: no input
initial_ast: 9498c048747706d4478783a2801179d84243099c3867cb437f4141bf873fc381
unrolled_ast: 9498c048747706d4478783a2801179d84243099c3867cb437f4141bf873fc381
ssa_ast: 9498c048747706d4478783a2801179d84243099c3867cb437f4141bf873fc381
flattened_ast: 30e7fb13033f0a61d999026dbeafff5fe3938e4b6ed2cb709fc0a38ce98c8c57
initial_ast: 7bbcb1e7bfda82030ab22d46c5c0ee4d2a54553aae4d581dc78b16663896a5f3
unrolled_ast: 7bbcb1e7bfda82030ab22d46c5c0ee4d2a54553aae4d581dc78b16663896a5f3
ssa_ast: 7bbcb1e7bfda82030ab22d46c5c0ee4d2a54553aae4d581dc78b16663896a5f3
flattened_ast: 71d3b3288fd82eab7ea755fe82ead9a5d3885cdb983488a88b5d677dd80fb1e8

View File

@ -4,7 +4,7 @@ expectation: Pass
outputs:
- output:
- initial_input_ast: no input
initial_ast: 4fcaf4a3cc781ca66c4ed30d4704bfa5bc31715a9cce6c12c3b45ba13deebb5c
unrolled_ast: 4fcaf4a3cc781ca66c4ed30d4704bfa5bc31715a9cce6c12c3b45ba13deebb5c
ssa_ast: d511fa6a72cca8b7370691502a92837faac71965312b63e55ce372271720612a
flattened_ast: a085ceac6974fb2a2cbf32de9775e0dbe3c1ca1e1ad184141a8794df6f7bef32
initial_ast: 96a5dcffcccc268103191159bbed06386425b092edbd7ffea20f97c80c078f2d
unrolled_ast: 96a5dcffcccc268103191159bbed06386425b092edbd7ffea20f97c80c078f2d
ssa_ast: 058ff955144948b6b26f3c529e18a4e20e74fcd328bd910f6d5f0771f35298d6
flattened_ast: f1b6acd125e8792ea90e5d8d43ce042795402542fa12e85e5644249cd8ae9f3b

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372042]: `finalize` expected `2` args, but got `3`\n --> compiler-test:8:5\n |\n 8 | finalize(receiver, amount, amount);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
- "Error [ETYC0372042]: `finalize` expected `2` args, but got `3`\n --> compiler-test:8:11\n |\n 8 | async finalize(receiver, amount, amount);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"

View File

@ -4,7 +4,7 @@ expectation: Pass
outputs:
- output:
- initial_input_ast: no input
initial_ast: 20577705e80224f486f237ba98fb33550fec7fb0a724eb9c339067a561d426e6
unrolled_ast: 20577705e80224f486f237ba98fb33550fec7fb0a724eb9c339067a561d426e6
ssa_ast: 20577705e80224f486f237ba98fb33550fec7fb0a724eb9c339067a561d426e6
flattened_ast: 6babfacc82c1283848fc1926ca778d6a3c7a46148cfe93fec13927ed31bd950a
initial_ast: 07adbfa271d270412b653f4c6d70028eae8bfa4b5228bc18d3059625a6b8b6ad
unrolled_ast: 07adbfa271d270412b653f4c6d70028eae8bfa4b5228bc18d3059625a6b8b6ad
ssa_ast: 07adbfa271d270412b653f4c6d70028eae8bfa4b5228bc18d3059625a6b8b6ad
flattened_ast: a8d61140c04832c275255f8c6cdeadbb99264b67e498a3bfb2ed0d452f21aaf2

View File

@ -4,7 +4,7 @@ expectation: Pass
outputs:
- output:
- initial_input_ast: no input
initial_ast: 6d2ba5e3df5deb29bf51362eea982a821479038d0d30f9257f4e9e8d0940382b
unrolled_ast: 6d2ba5e3df5deb29bf51362eea982a821479038d0d30f9257f4e9e8d0940382b
ssa_ast: ff223290570b6b7fc4129ebe14589d07f6dd82f7adf0b0dfcc396a0adbb0286c
flattened_ast: 1ed84db6d2abc60c44c9780558a1210d29043069f57732f26411f6bdb267bddf
initial_ast: 5031143bae1fe94f0e9e01a59caf03a37556f8d62cc1fc6294f553771612300e
unrolled_ast: 5031143bae1fe94f0e9e01a59caf03a37556f8d62cc1fc6294f553771612300e
ssa_ast: 0e6c2552a18f992e5525b5c0d30665cd671d974713b4bd12b928e1c943bac62c
flattened_ast: 01d338d8fdd7f54f884f1e5fc46d80fba52c2005c228f072d5f4a5aabbd40cda

View File

@ -5,18 +5,18 @@ outputs:
- Finalize:
arguments: []
span:
lo: 0
hi: 10
lo: 6
hi: 16
- Finalize:
arguments:
- Identifier: "{\"name\":\"foo\",\"span\":\"{\\\"lo\\\":9,\\\"hi\\\":12}\"}"
- Identifier: "{\"name\":\"foo\",\"span\":\"{\\\"lo\\\":15,\\\"hi\\\":18}\"}"
span:
lo: 0
hi: 13
lo: 6
hi: 19
- Finalize:
arguments:
- Identifier: "{\"name\":\"foo\",\"span\":\"{\\\"lo\\\":9,\\\"hi\\\":12}\"}"
- Identifier: "{\"name\":\"bar\",\"span\":\"{\\\"lo\\\":14,\\\"hi\\\":17}\"}"
- Identifier: "{\"name\":\"foo\",\"span\":\"{\\\"lo\\\":15,\\\"hi\\\":18}\"}"
- Identifier: "{\"name\":\"bar\",\"span\":\"{\\\"lo\\\":20,\\\"hi\\\":23}\"}"
span:
lo: 0
hi: 18
lo: 6
hi: 24

View File

@ -2,6 +2,9 @@
namespace: ParseStatement
expectation: Fail
outputs:
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ';'\n --> test:1:10\n |\n 1 | finalize(;\n | ^"
- "Error [EPAR0370009]: unexpected string: expected 'expression', found ','\n --> test:1:15\n |\n 1 | finalize(foo, ,);\n | ^"
- "Error [EPAR0370005]: expected ; -- found '<eof>'\n --> test:1:18\n |\n 1 | finalize(foo, bar)\n | ^"
- "Error [EPAR0370029]: A finalize statement must be preceded by the `async` keyword.\n --> test:1:1\n |\n 1 | finalize(;\n | ^^^^^^^^\n |\n = Add the `async` keyword before the `finalize` keyword."
- "Error [EPAR0370029]: A finalize statement must be preceded by the `async` keyword.\n --> test:1:1\n |\n 1 | finalize(foo, ,);\n | ^^^^^^^^\n |\n = Add the `async` keyword before the `finalize` keyword."
- "Error [EPAR0370029]: A finalize statement must be preceded by the `async` keyword.\n --> test:1:1\n |\n 1 | finalize(foo, bar)\n | ^^^^^^^^\n |\n = Add the `async` keyword before the `finalize` keyword."
- "Error [EPAR0370005]: expected finalize -- found 'async'\n --> test:1:7\n |\n 1 | async async finalize(foo);\n | ^^^^^"
- "Error [EPAR0370029]: A finalize statement must be preceded by the `async` keyword.\n --> test:1:1\n |\n 1 | finalize;\n | ^^^^^^^^\n |\n = Add the `async` keyword before the `finalize` keyword."
- "Error [EPAR0370005]: expected ; -- found 'finalize'\n --> test:1:6\n |\n 1 | asyn finalize(foo);\n | ^^^^^^^^"

View File

@ -3,8 +3,8 @@ namespace: ParseStatement
expectation: Pass
*/
finalize();
async finalize();
finalize(foo);
async finalize(foo);
finalize(foo, bar);
async finalize(foo, bar);

View File

@ -8,3 +8,9 @@ finalize(;
finalize(foo, ,);
finalize(foo, bar)
async async finalize(foo);
finalize;
asyn finalize(foo);