Some bug fixes; update some examples

This commit is contained in:
Pranav Gaddamadugu 2022-10-05 15:27:54 -07:00
parent e15e8f05d6
commit 8283c922f6
12 changed files with 842 additions and 857 deletions

View File

@ -51,8 +51,6 @@ pub struct Compiler<'a> {
pub input_ast: Option<InputAst>,
/// Compiler options on some optional output files.
output_options: OutputOptions,
/// Whether or not we are compiling an imported program.
is_import: bool,
}
impl<'a> Compiler<'a> {
@ -64,7 +62,6 @@ impl<'a> Compiler<'a> {
main_file_path: PathBuf,
output_directory: PathBuf,
output_options: Option<OutputOptions>,
is_import: bool,
) -> Self {
Self {
handler,
@ -75,7 +72,6 @@ impl<'a> Compiler<'a> {
ast: Ast::new(Program::default()),
input_ast: None,
output_options: output_options.unwrap_or_default(),
is_import,
}
}
@ -107,8 +103,8 @@ impl<'a> Compiler<'a> {
let program_scope = self.ast.ast.program_scopes.values().next().unwrap();
let program_scope_name =
with_session_globals(|s| program_scope.name.name.as_str(s, |string| string.to_string()));
if self.is_import && program_scope_name != self.program_name {
return Err(CompilerError::imported_program_name_does_not_match_filename(
if program_scope_name != self.program_name {
return Err(CompilerError::program_scope_name_does_not_match(
program_scope_name,
self.program_name.clone(),
program_scope.name.span,

View File

@ -60,7 +60,6 @@ fn new_compiler(handler: &Handler, main_file_path: PathBuf) -> Compiler<'_> {
ssa_ast: true,
flattened_ast: true,
}),
false,
)
}

View File

@ -65,9 +65,9 @@ create_messages!(
}
@formatted
imported_program_name_does_not_match_filename {
program_scope_name_does_not_match {
args: (program_scope_name: impl Display, file_name: impl Display),
msg: format!("The program scope `{program_scope_name}` does not match its filename `{file_name}`."),
msg: format!("The program scope name `{program_scope_name}` must match `{file_name}`."),
help: None,
}
);

View File

@ -1,67 +1,70 @@
// A bid in an auction.
// - `owner` : The address of the account that owns the record associated with this bid.
// This is separate from the address of the account that placed the bid.
// - `gates` : The value associated with the record (always zero).
// - `bidder` : The address of the account that placed the bid.
// - `amount` : The amount of the bid.
// - `is_winner` : Whether the bid is the winning bid.
record Bid {
owner: address,
gates: u64,
bidder: address,
amount: u64,
is_winner: bool,
}
program auction.aleo {
// A bid in an auction.
// - `owner` : The address of the account that owns the record associated with this bid.
// This is separate from the address of the account that placed the bid.
// - `gates` : The value associated with the record (always zero).
// - `bidder` : The address of the account that placed the bid.
// - `amount` : The amount of the bid.
// - `is_winner` : Whether the bid is the winning bid.
record Bid {
owner: address,
gates: u64,
bidder: address,
amount: u64,
is_winner: bool,
}
// Returns a new bid.
// - `bidder` : The address of the account that placed the bid.
// - `amount` : The amount of the bid.
// Requires that `bidder` matches the function caller.
// The owner of the record is set to the entity responsible for running the auction (auction runner).
// The address of the auction runner is aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh.
transition place_bid(bidder: address, amount: u64) -> Bid {
// Ensure the caller is the auction bidder.
console.assert_eq(self.caller, bidder);
// Return a new 'Bid' record for the auction bidder.
return Bid {
owner: aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh,
gates: 0u64,
bidder: bidder,
amount: amount,
is_winner: false,
};
}
// Returns a new bid.
// - `bidder` : The address of the account that placed the bid.
// - `amount` : The amount of the bid.
// Requires that `bidder` matches the function caller.
// The owner of the record is set to the entity responsible for running the auction (auction runner).
// The address of the auction runner is aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh.
transition place_bid(bidder: address, amount: u64) -> Bid {
// Ensure the caller is the auction bidder.
console.assert_eq(self.caller, bidder);
// Return a new 'Bid' record for the auction bidder.
return Bid {
owner: aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh,
gates: 0u64,
bidder: bidder,
amount: amount,
is_winner: false,
};
}
// Returns the winning bid.
// - `first` : The first bid.
// - `second` : The second bid.
// Requires that the function caller is the auction runner.
// Assumes that the function is invoked only after the bidding period has ended.
// In the event of a tie, the first bid is selected.
transition resolve(first: Bid, second: Bid) -> Bid {
// Ensure the caller is the auctioneer.
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
// Resolve the winner of the auction.
if (first.amount >= second.amount) {
return first;
} else {
return second;
// Returns the winning bid.
// - `first` : The first bid.
// - `second` : The second bid.
// Requires that the function caller is the auction runner.
// Assumes that the function is invoked only after the bidding period has ended.
// In the event of a tie, the first bid is selected.
transition resolve(first: Bid, second: Bid) -> Bid {
// Ensure the caller is the auctioneer.
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
// Resolve the winner of the auction.
if (first.amount >= second.amount) {
return first;
} else {
return second;
}
}
// Returns ownership of the bid to bidder.
// - `bid` : The winning bid.
// Requires that the function caller is the auction runner.
// Assumes that the function is invoked only after all bids have been resolved.
transition finish(bid: Bid) -> Bid {
// Ensure the caller is the auctioneer.
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
// Return 'is_winner' as 'true' in the winning 'Bid'.
return Bid {
owner: bid.bidder,
gates: bid.gates,
bidder: bid.bidder,
amount: bid.amount,
is_winner: true,
};
}
}
// Returns ownership of the bid to bidder.
// - `bid` : The winning bid.
// Requires that the function caller is the auction runner.
// Assumes that the function is invoked only after all bids have been resolved.
transition finish(bid: Bid) -> Bid {
// Ensure the caller is the auctioneer.
console.assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh);
// Return 'is_winner' as 'true' in the winning 'Bid'.
return Bid {
owner: bid.bidder,
gates: bid.gates,
bidder: bid.bidder,
amount: bid.amount,
is_winner: true,
};
}

View File

@ -1,104 +1,103 @@
// A token, issued by a bank.
// - 'owner' : The address of the account that owns the record associated with this token.
// - 'gates' : The value associated with the record (always zero).
// - 'amount' : The amount of tokens owned by the account.
record Token {
owner: address,
gates: u64,
amount: u64,
}
// An on-chain mapping, storing the amount of tokens owned by each account
// The account is stored as a to preserve user privacy.
mapping balances: field => u64;
// Returns a new Token.
// - `owner` : The address of the account to issue the token to.
// - `amount`: The amount of tokens to issue.
// Requires that the function caller is the bank.
// The bank's address is aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a.
transition issue(owner: address, amount: u64) -> Token {
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
return Token {
owner: owner,
gates: 0u64,
amount: amount,
};
}
// Deposits some amount of money into the bank.
// Returns a new Token with the remaining amount of money.
// - `token` : A record containing tokens to deposit.
// - `amount`: The amount of tokens to deposit.
transition deposit(token: Token, amount: u64) -> Token {
let difference: u64 = token.amount - amount;
let remaining: Token = Token {
owner: token.owner,
gates: token.gates,
amount: difference,
};
// Compute the hash of the token owner.
let hash: field = BHP256::hash(token.owner);
async finalize(hash, amount);
return remaining;
}
// Updates on-chain state by the amount of tokens deposited.
// - `hash` : The hash of the token owner.
// - `amount`: The amount of tokens that were deposited.
finalize deposit(hash: field, amount: u64) {
increment(balances, hash, amount);
}
// Returns a new Token containing the amount of money withdrawn.
// - `recipient`: The address of the account to withdraw the tokens to.
// - `amount` : The amount of tokens to withdraw.
// - `rate` : The compound interest rate.
// - `periods` : The number of periods to compound the interest over.
// Requires that the function caller is the bank.
transition withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> Token {
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
let hash: field = BHP256::hash(recipient);
let total: u64 = calculate_interest(amount, rate, periods);
let token: Token = Token {
owner: recipient,
gates: 0u64,
amount: total,
};
async finalize(hash, amount);
return token;
}
// Updates on-chain state by the amount of tokens withdrawn.
// - `hash` : The hash of the token owner.
// - `amount`: The amount of tokens that were withdrawn.
finalize withdraw(hash: field, amount: u64) {
decrement(balances, hash, amount);
}
// Returns the total amount of tokens after compounding interest.
// - `principal`: The amount of tokens to compound interest over.
// - `rate` : The compound interest rate.
// - `periods` : The number of periods to compound the interest over.
function calculate_interest(principal: u64, rate: u64, periods: u64) -> u64 {
let amount: u64 = principal;
for i:u64 in 0u64..100u64 {
if i < periods {
amount += (amount * rate) / 10000u64;
}
program basic_bank.aleo {
// A token, issued by a bank.
// - 'owner' : The address of the account that owns the record associated with this token.
// - 'gates' : The value associated with the record (always zero).
// - 'amount' : The amount of tokens owned by the account.
record Token {
owner: address,
gates: u64,
amount: u64,
}
return amount;
// An on-chain mapping, storing the amount of tokens owned by each account
// The account is stored as a to preserve user privacy.
mapping balances: field => u64;
// Returns a new Token.
// - `owner` : The address of the account to issue the token to.
// - `amount`: The amount of tokens to issue.
// Requires that the function caller is the bank.
// The bank's address is aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a.
transition issue(owner: address, amount: u64) -> Token {
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
return Token {
owner: owner,
gates: 0u64,
amount: amount,
};
}
// Deposits some amount of money into the bank.
// Returns a new Token with the remaining amount of money.
// - `token` : A record containing tokens to deposit.
// - `amount`: The amount of tokens to deposit.
transition deposit(token: Token, amount: u64) -> Token {
let difference: u64 = token.amount - amount;
let remaining: Token = Token {
owner: token.owner,
gates: token.gates,
amount: difference,
};
// Compute the hash of the token owner.
let hash: field = BHP256::hash(token.owner);
async finalize(hash, amount);
return remaining;
}
// Updates on-chain state by the amount of tokens deposited.
// - `hash` : The hash of the token owner.
// - `amount`: The amount of tokens that were deposited.
finalize deposit(hash: field, amount: u64) {
increment(balances, hash, amount);
}
// Returns a new Token containing the amount of money withdrawn.
// - `recipient`: The address of the account to withdraw the tokens to.
// - `amount` : The amount of tokens to withdraw.
// - `rate` : The compound interest rate.
// - `periods` : The number of periods to compound the interest over.
// Requires that the function caller is the bank.
transition withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> Token {
console.assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a);
let hash: field = BHP256::hash(recipient);
let total: u64 = calculate_interest(amount, rate, periods);
let token: Token = Token {
owner: recipient,
gates: 0u64,
amount: total,
};
async finalize(hash, amount);
return token;
}
// Updates on-chain state by the amount of tokens withdrawn.
// - `hash` : The hash of the token owner.
// - `amount`: The amount of tokens that were withdrawn.
finalize withdraw(hash: field, amount: u64) {
decrement(balances, hash, amount);
}
// Returns the total amount of tokens after compounding interest.
// - `principal`: The amount of tokens to compound interest over.
// - `rate` : The compound interest rate.
// - `periods` : The number of periods to compound the interest over.
function calculate_interest(principal: u64, rate: u64, periods: u64) -> u64 {
let amount: u64 = principal;
for i:u64 in 0u64..100u64 {
if i < periods {
amount += (amount * rate) / 10000u64;
}
}
return amount;
}
}

View File

@ -1,113 +1,115 @@
// Battleship boards are represented by 8x8 squares.
// A u64 is all that is required to represent a hit or a miss on a single board.
// Starting from the top row, left to right, a hit is 1 and a miss is 0.
// A first move resulting in a hit in row 1, column 3 would be:
// 00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
// A second u64 is needed to represent which squares have been played, with 1s being played squares and 0s being
// unplayed squares.
record board_state {
owner: address,
gates: u64,
// The hits and misses registered on the opponent's board.
hits_and_misses: u64,
// The squares that have been played on the opponent's board.
played_tiles: u64,
// The ship bitstring representing all ship positions on your own board
ships: u64,
player_1: address,
player_2: address,
game_started: bool,
}
// Returns a new board_state.
transition new_board_state(
ships: u64,
opponent: address,
) -> board_state {
return board_state {
owner: self.caller,
gates: 0u64,
hits_and_misses: 0u64,
played_tiles: 0u64,
ships,
player_1: self.caller,
player_2: opponent,
game_started: false,
};
}
// Returns a new board state that has been started.
// Fails if this board has been started before.
transition start_board(
// The record of the board to start. A board can only be started once.
board: board_state,
) -> board_state {
// Ensure this board hasn't been used to start a game before.
console.assert(!board.game_started);
return board_state {
owner: board.owner,
gates: board.gates,
hits_and_misses: board.hits_and_misses,
played_tiles: board.played_tiles,
ships: board.ships,
player_1: board.player_1,
player_2: board.player_2,
game_started: true,
};
}
// Returns a new board state record that includes all the played tiles.
// Fails if r1 has been played before.
transition update_played_tiles(
// The record of the board to update.
board: board_state,
// The u64 equivalent of a bitstring fire coordinate to send to the opponent.
shoot: u64,
) -> board_state {
// Need to make sure r1 is a valid move. Only one bit of r1 should be flipped.
let flip_bit: u64 = shoot - 1u64;
// bitwise and operation
let check_move: u64 = shoot & flip_bit;
console.assert_eq(check_move, 0u64);
// Need to make sure r1 is a valid move given the played_tiles. no bits should overlap.
let check_tiles: u64 = shoot & board.played_tiles;
console.assert_eq(check_tiles, 0u64);
// Update played tiles.
let played_tiles: u64 = board.played_tiles | shoot;
return board_state {
owner: board.owner,
gates: board.gates,
hits_and_misses: board.hits_and_misses,
played_tiles,
ships: board.ships,
player_1: board.player_1,
player_2: board.player_2,
game_started: board.game_started,
};
}
// Returns a new board state record that includes all the hits and misses.
transition update_hits_and_misses(
// The record of the board to update.
board: board_state,
// The u64 equivalent of a bitstring of whether this player's previous move was a hit or miss.
hit_or_miss: u64,
) -> board_state {
// Update hits and misses.
let hits_and_misses: u64 = board.hits_and_misses | hit_or_miss;
return board_state {
owner: board.owner,
gates: board.gates,
hits_and_misses,
played_tiles: board.played_tiles,
ships: board.ships,
player_1: board.player_1,
player_2: board.player_2,
game_started: board.game_started,
};
program board.aleo {
// Battleship boards are represented by 8x8 squares.
// A u64 is all that is required to represent a hit or a miss on a single board.
// Starting from the top row, left to right, a hit is 1 and a miss is 0.
// A first move resulting in a hit in row 1, column 3 would be:
// 00100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
// A second u64 is needed to represent which squares have been played, with 1s being played squares and 0s being
// unplayed squares.
record board_state {
owner: address,
gates: u64,
// The hits and misses registered on the opponent's board.
hits_and_misses: u64,
// The squares that have been played on the opponent's board.
played_tiles: u64,
// The ship bitstring representing all ship positions on your own board
ships: u64,
player_1: address,
player_2: address,
game_started: bool,
}
// Returns a new board_state.
transition new_board_state(
ships: u64,
opponent: address,
) -> board_state {
return board_state {
owner: self.caller,
gates: 0u64,
hits_and_misses: 0u64,
played_tiles: 0u64,
ships,
player_1: self.caller,
player_2: opponent,
game_started: false,
};
}
// Returns a new board state that has been started.
// Fails if this board has been started before.
transition start_board(
// The record of the board to start. A board can only be started once.
board: board_state,
) -> board_state {
// Ensure this board hasn't been used to start a game before.
console.assert(!board.game_started);
return board_state {
owner: board.owner,
gates: board.gates,
hits_and_misses: board.hits_and_misses,
played_tiles: board.played_tiles,
ships: board.ships,
player_1: board.player_1,
player_2: board.player_2,
game_started: true,
};
}
// Returns a new board state record that includes all the played tiles.
// Fails if r1 has been played before.
transition update_played_tiles(
// The record of the board to update.
board: board_state,
// The u64 equivalent of a bitstring fire coordinate to send to the opponent.
shoot: u64,
) -> board_state {
// Need to make sure r1 is a valid move. Only one bit of r1 should be flipped.
let flip_bit: u64 = shoot - 1u64;
// bitwise and operation
let check_move: u64 = shoot & flip_bit;
console.assert_eq(check_move, 0u64);
// Need to make sure r1 is a valid move given the played_tiles. no bits should overlap.
let check_tiles: u64 = shoot & board.played_tiles;
console.assert_eq(check_tiles, 0u64);
// Update played tiles.
let played_tiles: u64 = board.played_tiles | shoot;
return board_state {
owner: board.owner,
gates: board.gates,
hits_and_misses: board.hits_and_misses,
played_tiles,
ships: board.ships,
player_1: board.player_1,
player_2: board.player_2,
game_started: board.game_started,
};
}
// Returns a new board state record that includes all the hits and misses.
transition update_hits_and_misses(
// The record of the board to update.
board: board_state,
// The u64 equivalent of a bitstring of whether this player's previous move was a hit or miss.
hit_or_miss: u64,
) -> board_state {
// Update hits and misses.
let hits_and_misses: u64 = board.hits_and_misses | hit_or_miss;
return board_state {
owner: board.owner,
gates: board.gates,
hits_and_misses,
played_tiles: board.played_tiles,
ships: board.ships,
player_1: board.player_1,
player_2: board.player_2,
game_started: board.game_started,
};
}
}

View File

@ -1,46 +1,49 @@
record move {
owner: address,
gates: u64,
incoming_fire_coordinate: u64,
player_1: address,
player_2: address,
// One flipped bit indicates a hit. No flipped bits indicates a miss.
prev_hit_or_miss: u64,
program move.aleo {
record move {
owner: address,
gates: u64,
incoming_fire_coordinate: u64,
player_1: address,
player_2: address,
// One flipped bit indicates a hit. No flipped bits indicates a miss.
prev_hit_or_miss: u64,
}
// Returns new move record owned by the opponent.
transition create_move(
// The move record created by the opponent.
move_record: move,
// The u64 representation of incoming_fire_coordinate, the bitstring fire coordinate to send to the opponent.
incoming_fire_coordinate: u64,
// The u64 representation of prev_hit_or_miss, this player's previous fire coordinate as a hit or miss.
prev_hit_or_miss: u64,
) -> move {
// A new move record should be created and owned by the opponent.
let one_is_owner: bool = move_record.player_1 == move_record.owner;
let opponent: address = one_is_owner ? move_record.player_2 : move_record.player_1;
return move {
owner: opponent,
gates: move_record.gates,
incoming_fire_coordinate,
player_1: move_record.player_2,
player_2: move_record.player_1,
prev_hit_or_miss,
};
}
// Returns the move record owned by the opponent.
// Note, this move record contains dummy fire coordinates and previous hit or miss.
transition start_game(player_2: address) -> move {
return move {
owner: player_2,
gates: 0u64,
incoming_fire_coordinate: 0u64,
player_1: self.caller,
player_2: player_2,
prev_hit_or_miss: 0u64,
};
}
}
// Returns new move record owned by the opponent.
transition create_move(
// The move record created by the opponent.
move_record: move,
// The u64 representation of incoming_fire_coordinate, the bitstring fire coordinate to send to the opponent.
incoming_fire_coordinate: u64,
// The u64 representation of prev_hit_or_miss, this player's previous fire coordinate as a hit or miss.
prev_hit_or_miss: u64,
) -> move {
// A new move record should be created and owned by the opponent.
let one_is_owner: bool = move_record.player_1 == move_record.owner;
let opponent: address = one_is_owner ? move_record.player_2 : move_record.player_1;
return move {
owner: opponent,
gates: move_record.gates,
incoming_fire_coordinate,
player_1: move_record.player_2,
player_2: move_record.player_1,
prev_hit_or_miss,
};
}
// Returns the move record owned by the opponent.
// Note, this move record contains dummy fire coordinates and previous hit or miss.
transition start_game(player_2: address) -> move {
return move {
owner: player_2,
gates: 0u64,
incoming_fire_coordinate: 0u64,
player_1: self.caller,
player_2: player_2,
prev_hit_or_miss: 0u64,
};
}

View File

@ -1,123 +1,125 @@
// Returns the number of flipped bits.
// E.g. 17870283321406128128u64, in binary 11111000 00000000 00000000 00000000 00000000 00000000 00000000 00000000,
// returns 5u64;
function bitcount(bits: u64) -> u64 {
let r1: u64 = bits / 2u64;
let r2: u64 = bits / 4u64;
let r3: u64 = bits / 8u64;
program verify.aleo {
// Returns the number of flipped bits.
// E.g. 17870283321406128128u64, in binary 11111000 00000000 00000000 00000000 00000000 00000000 00000000 00000000,
// returns 5u64;
function bitcount(bits: u64) -> u64 {
let r1: u64 = bits / 2u64;
let r2: u64 = bits / 4u64;
let r3: u64 = bits / 8u64;
let r4: u64 = r1 & 8608480567731124087u64;
let r5: u64 = r2 & 3689348814741910323u64;
let r6: u64 = r3 & 1229782938247303441u64;
let r4: u64 = r1 & 8608480567731124087u64;
let r5: u64 = r2 & 3689348814741910323u64;
let r6: u64 = r3 & 1229782938247303441u64;
let r7: u64 = bits - r4 - r5 - r6;
let r7: u64 = bits - r4 - r5 - r6;
let r8: u64 = r7 / 16u64;
let r9: u64 = r7 + r8;
let r10: u64 = r9 & 1085102592571150095u64;
let r11: u64 = r10 % 255u64;
let r8: u64 = r7 / 16u64;
let r9: u64 = r7 + r8;
let r10: u64 = r9 & 1085102592571150095u64;
let r11: u64 = r10 % 255u64;
return r11;
return r11;
}
// Returns boolean of whether all the flipped bits in location are "adjacent". Horizontally, this means all flipped bits are
// directly next to each other (111). Vertically, this means all flipped bits are separated by 7 unflipped bits
// (10000000100000001).
function adjacency_check(
// The u64 representation of a ship's placement in an 8x8 grid.
ship: u64,
// The u64 representation of a ship's bitstring, either horizontally or vertically.
// E.g. a ship of length 3's bit string horizontally would be: 000111 = 7u64. Vertically, the bit string would be:
// 10000000100000001 = 65793u64.
orientation: u64,
) -> bool {
// This may result in 0.
let division: u64 = ship / orientation;
// subtracting 1 from 0 will cause an underflow, so we should check for this edge case.
let is_eq: bool = division == 0u64;
// if the above division resulted in 0, we know the adjacency check should return false.
// Setting to r4 to 3 (11) will guarantee failure here.
let ternary: u64 = is_eq ? 3u64 : division;
let subtraction: u64 = ternary - 1u64;
let and: u64 = subtraction & ternary;
let bits_are_adjacent: bool = and == 0u64;
return bits_are_adjacent;
}
// Returns boolean of whether adjacent flipped bits don't split a row of size 8.
// E.g. 111000000 has adjacent flipped bits but splits a row: 00000001 11000000
function horizontal_check(
// The u64 representation of a ship's placement in an 8x8 grid.
ship: u64,
// The u64 representation of a ship's bitstring horizontally.
horizontal: u64,
) -> bool {
let remainder: u64 = ship % 255u64;
// This may result in 0.
let division: u64 = remainder / horizontal;
// Subtracting 1 from 0 will cause an underflow.
let is_eq: bool = division == 0u64;
// Setting to 3 will guarantee failure.
let ternary: u64 = is_eq ? 3u64 : division;
let subtraction: u64 = ternary - 1u64;
let and: u64 = subtraction & ternary;
let bits_split_row: bool = and == 0u64;
return bits_split_row;
}
// Returns `true` if the ship placement is valid.
transition validate_ship(
// The u64 representation of a ship's placement in an 8x8 grid.
ship: u64,
// The length of the placed ship.
length: u64,
// The u64 equivalent of a ship's horizontal bitstring representation.
horizontal: u64,
// The u64 equivalent of a ship's vertical bitstring representation.
vertical: u64,
) -> bool {
// Check bitcount -- all other validations depend on the bitcount being correct.
let num_bits: u64 = bitcount(ship);
console.assert_eq(num_bits, length);
// Check horizontal bits of ship.
let is_adjacent: bool = adjacency_check(ship, horizontal); // True if bits are adjacent horizontally.
let is_horizontal: bool = horizontal_check(ship, horizontal); // True if those horizontal bits are not split across rows.
let valid_horizontal: bool = is_adjacent && is_horizontal; // True if bits are adjacent horizontally and not split across rows.
// Check vertical bits of ship.
let valid_vertical: bool = adjacency_check(ship, vertical); // True if bits are adjacent vertically.
let ship_is_valid: bool = valid_horizontal || valid_vertical; // Ship is valid if it is vertically or horizontally valid.
return ship_is_valid;
}
// Returns the u64 representation of all the ships' placements in an 8x8 grid. This function will fail
// if any of the ship placements overlap each other.
transition create_board(
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
carrier: u64,
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
battleship: u64,
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
cruiser: u64,
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
destroyer: u64,
) -> u64 {
// Bitwise combine the ship placements together
let ships: u64 = carrier | battleship | cruiser | destroyer;
let num_bits: u64 = bitcount(ships);
console.assert_eq(num_bits, 14u64); // Given 4 individually-valid ships, a valid combination should yield exactly 14 flipped bits.
return ships;
}
}
// Returns boolean of whether all the flipped bits in location are "adjacent". Horizontally, this means all flipped bits are
// directly next to each other (111). Vertically, this means all flipped bits are separated by 7 unflipped bits
// (10000000100000001).
function adjacency_check(
// The u64 representation of a ship's placement in an 8x8 grid.
ship: u64,
// The u64 representation of a ship's bitstring, either horizontally or vertically.
// E.g. a ship of length 3's bit string horizontally would be: 000111 = 7u64. Vertically, the bit string would be:
// 10000000100000001 = 65793u64.
orientation: u64,
) -> bool {
// This may result in 0.
let division: u64 = ship / orientation;
// subtracting 1 from 0 will cause an underflow, so we should check for this edge case.
let is_eq: bool = division == 0u64;
// if the above division resulted in 0, we know the adjacency check should return false.
// Setting to r4 to 3 (11) will guarantee failure here.
let ternary: u64 = is_eq ? 3u64 : division;
let subtraction: u64 = ternary - 1u64;
let and: u64 = subtraction & ternary;
let bits_are_adjacent: bool = and == 0u64;
return bits_are_adjacent;
}
// Returns boolean of whether adjacent flipped bits don't split a row of size 8.
// E.g. 111000000 has adjacent flipped bits but splits a row: 00000001 11000000
function horizontal_check(
// The u64 representation of a ship's placement in an 8x8 grid.
ship: u64,
// The u64 representation of a ship's bitstring horizontally.
horizontal: u64,
) -> bool {
let remainder: u64 = ship % 255u64;
// This may result in 0.
let division: u64 = remainder / horizontal;
// Subtracting 1 from 0 will cause an underflow.
let is_eq: bool = division == 0u64;
// Setting to 3 will guarantee failure.
let ternary: u64 = is_eq ? 3u64 : division;
let subtraction: u64 = ternary - 1u64;
let and: u64 = subtraction & ternary;
let bits_split_row: bool = and == 0u64;
return bits_split_row;
}
// Returns `true` if the ship placement is valid.
transition validate_ship(
// The u64 representation of a ship's placement in an 8x8 grid.
ship: u64,
// The length of the placed ship.
length: u64,
// The u64 equivalent of a ship's horizontal bitstring representation.
horizontal: u64,
// The u64 equivalent of a ship's vertical bitstring representation.
vertical: u64,
) -> bool {
// Check bitcount -- all other validations depend on the bitcount being correct.
let num_bits: u64 = bitcount(ship);
console.assert_eq(num_bits, length);
// Check horizontal bits of ship.
let is_adjacent: bool = adjacency_check(ship, horizontal); // True if bits are adjacent horizontally.
let is_horizontal: bool = horizontal_check(ship, horizontal); // True if those horizontal bits are not split across rows.
let valid_horizontal: bool = is_adjacent && is_horizontal; // True if bits are adjacent horizontally and not split across rows.
// Check vertical bits of ship.
let valid_vertical: bool = adjacency_check(ship, vertical); // True if bits are adjacent vertically.
let ship_is_valid: bool = valid_horizontal || valid_vertical; // Ship is valid if it is vertically or horizontally valid.
return ship_is_valid;
}
// Returns the u64 representation of all the ships' placements in an 8x8 grid. This function will fail
// if any of the ship placements overlap each other.
transition create_board(
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
carrier: u64,
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
battleship: u64,
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
cruiser: u64,
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
destroyer: u64,
) -> u64 {
// Bitwise combine the ship placements together
let ships: u64 = carrier | battleship | cruiser | destroyer;
let num_bits: u64 = bitcount(ships);
console.assert_eq(num_bits, 14u64); // Given 4 individually-valid ships, a valid combination should yield exactly 14 flipped bits.
return ships;
}

View File

@ -1,102 +1,105 @@
// The 'battleship.leo' program.
import board.leo;
import move.leo;
import verify.leo;
// Returns a new record representing a new game of battleship.
transition initialize_board(
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
carrier: u64,
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
battleship: u64,
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
cruiser: u64,
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
destroyer: u64,
// The address of the opponent.
player: address,
) -> board.leo/board_state.record {
// Verify that each individual ship placement bitstring is valid.
let valid_carrier: bool = verify.leo/validate_ship(carrier, 5u64, 31u64, 4311810305u64);
console.assert(valid_carrier);
// The 'battleship.leo' program.
program battleship.aleo {
// Returns a new record representing a new game of battleship.
transition initialize_board(
// The u64 representation of a carrier's placement in an 8x8 grid. Length = 5.
carrier: u64,
// The u64 representation of a battleship's placement in an 8x8 grid. Length = 4.
battleship: u64,
// The u64 representation of a cruiser's placement in an 8x8 grid. Length = 3.
cruiser: u64,
// The u64 representation of a destroyer's placement in an 8x8 grid. Length = 2.
destroyer: u64,
// The address of the opponent.
player: address,
) -> board.leo/board_state.record {
// Verify that each individual ship placement bitstring is valid.
let valid_carrier: bool = verify.leo/validate_ship(carrier, 5u64, 31u64, 4311810305u64);
console.assert(valid_carrier);
let valid_battleship: bool = verify.leo/validate_ship(battleship, 4u64, 15u64, 16843009u64);
console.assert(valid_battleship);
let valid_battleship: bool = verify.leo/validate_ship(battleship, 4u64, 15u64, 16843009u64);
console.assert(valid_battleship);
let valid_cruiser: bool = verify.leo/validate_ship(cruiser, 3u64, 7u64, 65793u64);
console.assert(valid_cruiser);
let valid_cruiser: bool = verify.leo/validate_ship(cruiser, 3u64, 7u64, 65793u64);
console.assert(valid_cruiser);
let valid_destroyer: bool = verify.leo/validate_ship(destroyer, 2u64, 3u64, 257u64);
console.assert(valid_destroyer);
let valid_destroyer: bool = verify.leo/validate_ship(destroyer, 2u64, 3u64, 257u64);
console.assert(valid_destroyer);
// Create the board with all the ship placements combined.
let board: u64 = verify.leo/create_board(carrier, battleship, cruiser, destroyer);
// Create the board with all the ship placements combined.
let board: u64 = verify.leo/create_board(carrier, battleship, cruiser, destroyer);
// Initialize the board state record.
let state: board_state = board.leo/new_board_state(board, player);
// Initialize the board state record.
let state: board_state = board.leo/new_board_state(board, player);
return state;
return state;
}
// Returns an updated board state record that has been started. This board cannot be used to start any other games.
// Returns a dummy move record owned by the opponent.
// This function commits a given board to a game with an opponent and creates the initial dummy move.
transition offer_battleship(
// The board record to start a game with.
board: board.leo/board_state.record,
) -> (board.leo/board_state.record, move.leo/move.record) {
let state: board_state = board.leo/start_board(board);
let dummy: move = move.leo/start_game(board.player_2);
return (state, dummy);
}
// Returns updated board_state.record that has been started and can no longer be used to join or start new games.
// Returns dummy move record owned by the opponent.
transition start_battleship(
// The board record to play the game with.
board: board.leo/board_state.record,
// The move record to play to begin the game. This should be the dummy move record created from offer_battleship.
move_start: move.leo/move.record,
) -> (board.leo/board_state.record, move.leo/move.record) {
// Validate that the move players and board players match each other.
console.assert_eq(board.player_1, move_start.player_2);
console.assert_eq(board.player_2, move_start.player_1);
let state: board_state = board.leo/start_board(board);
let dummy: move = move.leo/start_game(board.player_2);
return (state, dummy);
}
// Returns updated board record.
// Returns new move record owned by opponent.
transition play(
// The board record to update.
board: board.leo/board_state.record,
// The incoming move from the opponent.
move_incoming: move.leo/move.record,
// The u64 equivalent of the bitwise representation of the next coordinate to play on the opponent's board.
shoot: u64,
) -> (board.leo/board_state.record, move.leo/move.record) {
// Verify the board has been started. This prevents players from starting a game and then creating
// a brand new board to play with.
console.assert(board.game_started);
// Validate that the move players and board players match each other.
console.assert_eq(board.player_1, move_incoming.player_2);
console.assert_eq(board.player_2, move_incoming.player_1);
// Play coordinate on own board. Will fail if not a valid move.
let hit_or_miss: board_state = board.leo/update_played_tiles(board, shoot);
// Update own board with result of last shot.
let next_board: board_state = board.leo/update_hits_and_misses(hit_or_miss, move_incoming.prev_hit_or_miss);
// Assess whether incoming fire coordinate is a hit.
let is_hit: u64 = move_incoming.incoming_fire_coordinate & board.ships;
let next_move: move = move.leo/create_move(move_incoming, shoot, is_hit);
return (next_board, next_move);
}
}
// Returns an updated board state record that has been started. This board cannot be used to start any other games.
// Returns a dummy move record owned by the opponent.
// This function commits a given board to a game with an opponent and creates the initial dummy move.
transition offer_battleship(
// The board record to start a game with.
board: board.leo/board_state.record,
) -> (board.leo/board_state.record, move.leo/move.record) {
let state: board_state = board.leo/start_board(board);
let dummy: move = move.leo/start_game(board.player_2);
return (state, dummy);
}
// Returns updated board_state.record that has been started and can no longer be used to join or start new games.
// Returns dummy move record owned by the opponent.
transition start_battleship(
// The board record to play the game with.
board: board.leo/board_state.record,
// The move record to play to begin the game. This should be the dummy move record created from offer_battleship.
move_start: move.leo/move.record,
) -> (board.leo/board_state.record, move.leo/move.record) {
// Validate that the move players and board players match each other.
console.assert_eq(board.player_1, move_start.player_2);
console.assert_eq(board.player_2, move_start.player_1);
let state: board_state = board.leo/start_board(board);
let dummy: move = move.leo/start_game(board.player_2);
return (state, dummy);
}
// Returns updated board record.
// Returns new move record owned by opponent.
transition play(
// The board record to update.
board: board.leo/board_state.record,
// The incoming move from the opponent.
move_incoming: move.leo/move.record,
// The u64 equivalent of the bitwise representation of the next coordinate to play on the opponent's board.
shoot: u64,
) -> (board.leo/board_state.record, move.leo/move.record) {
// Verify the board has been started. This prevents players from starting a game and then creating
// a brand new board to play with.
console.assert(board.game_started);
// Validate that the move players and board players match each other.
console.assert_eq(board.player_1, move_incoming.player_2);
console.assert_eq(board.player_2, move_incoming.player_1);
// Play coordinate on own board. Will fail if not a valid move.
let hit_or_miss: board_state = board.leo/update_played_tiles(board, shoot);
// Update own board with result of last shot.
let next_board: board_state = board.leo/update_hits_and_misses(hit_or_miss, move_incoming.prev_hit_or_miss);
// Assess whether incoming fire coordinate is a hit.
let is_hit: u64 = move_incoming.incoming_fire_coordinate & board.ships;
let next_move: move = move.leo/create_move(move_incoming, shoot, is_hit);
return (next_board, next_move);
}

View File

@ -1,285 +1,287 @@
// Executes the bubble sorting algorithm.
// The original algorithm is given below.
//
// for i in 0..7 {
// for j in 0..7-i {
// // Move the smaller elements forward
// if arr[j+1] < arr[j] {
// // Swap the elements at indexes j and j+1
// let swap = arr[j];
// arr[j] = arr[j+1];
// arr[j+1] = swap;
// }
// }
// }
//
// Note that the implementation below uses tuples instead of arrays.
// The implementation also manually unrolls the loop.
program bubblesort.aleo {
// Executes the bubble sorting algorithm.
// The original algorithm is given below.
//
// for i in 0..7 {
// for j in 0..7-i {
// // Move the smaller elements forward
// if arr[j+1] < arr[j] {
// // Swap the elements at indexes j and j+1
// let swap = arr[j];
// arr[j] = arr[j+1];
// arr[j+1] = swap;
// }
// }
// }
//
// Note that the implementation below uses tuples instead of arrays.
// The implementation also manually unrolls the loop.
transition bubble_sort(
arr0: u32,
arr1: u32,
arr2: u32,
arr3: u32,
arr4: u32,
arr5: u32,
arr6: u32,
arr7: u32,
) -> (u32, u32, u32, u32, u32, u32, u32, u32) {
transition bubble_sort(
arr0: u32,
arr1: u32,
arr2: u32,
arr3: u32,
arr4: u32,
arr5: u32,
arr6: u32,
arr7: u32,
) -> (u32, u32, u32, u32, u32, u32, u32, u32) {
// Unroll the loops.
// Unroll the loops.
// (i, j) = (0, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
// (i, j) = (0, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (0, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (0, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (0, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (0, 4).
// Move the smaller elements forward.
if arr5 < arr4 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr4;
arr4 = arr5;
arr5 = temp;
}
// (i, j) = (0, 5).
// Move the smaller elements forward.
if arr6 < arr5 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr5;
arr5 = arr6;
arr6 = temp;
}
// (i, j) = (0, 6).
// Move the smaller elements forward.
if arr7 < arr6 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr6;
arr6 = arr7;
arr7 = temp;
}
// (i, j) = (1, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (1, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (1, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (1, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (1, 4).
// Move the smaller elements forward.
if arr5 < arr4 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr4;
arr4 = arr5;
arr5 = temp;
}
// (i, j) = (1, 5).
// Move the smaller elements forward.
if arr6 < arr5 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr5;
arr5 = arr6;
arr6 = temp;
}
// (i, j) = (2, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (2, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (2, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (2, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (2, 4).
// Move the smaller elements forward.
if arr5 < arr4 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr4;
arr4 = arr5;
arr5 = temp;
}
// (i, j) = (3, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (3, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (3, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (3, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (4, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (4, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (4, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (5, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (5, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (6, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
return (arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7);
}
// (i, j) = (0, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (0, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (0, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (0, 4).
// Move the smaller elements forward.
if arr5 < arr4 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr4;
arr4 = arr5;
arr5 = temp;
}
// (i, j) = (0, 5).
// Move the smaller elements forward.
if arr6 < arr5 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr5;
arr5 = arr6;
arr6 = temp;
}
// (i, j) = (0, 6).
// Move the smaller elements forward.
if arr7 < arr6 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr6;
arr6 = arr7;
arr7 = temp;
}
// (i, j) = (1, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (1, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (1, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (1, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (1, 4).
// Move the smaller elements forward.
if arr5 < arr4 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr4;
arr4 = arr5;
arr5 = temp;
}
// (i, j) = (1, 5).
// Move the smaller elements forward.
if arr6 < arr5 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr5;
arr5 = arr6;
arr6 = temp;
}
// (i, j) = (2, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (2, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (2, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (2, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (2, 4).
// Move the smaller elements forward.
if arr5 < arr4 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr4;
arr4 = arr5;
arr5 = temp;
}
// (i, j) = (3, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (3, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (3, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (3, 3).
// Move the smaller elements forward.
if arr4 < arr3 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr3;
arr3 = arr4;
arr4 = temp;
}
// (i, j) = (4, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (4, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (4, 2).
// Move the smaller elements forward.
if arr3 < arr2 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr2;
arr2 = arr3;
arr3 = temp;
}
// (i, j) = (5, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
// (i, j) = (5, 1).
// Move the smaller elements forward.
if arr2 < arr1 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr1;
arr1 = arr2;
arr2 = temp;
}
// (i, j) = (6, 0).
// Move the smaller elements forward.
if arr1 < arr0 {
// Swap the elements at indexes j and j+1
let temp: u32 = arr0;
arr0 = arr1;
arr1 = temp;
}
return (arr0, arr1, arr2, arr3, arr4, arr5, arr6, arr7);
}
}

View File

@ -217,59 +217,36 @@ fn compile_leo_file(
.and_then(|name| name.to_str())
.ok_or_else(PackageError::failed_to_get_file_name)?;
// Construct program name from file_path name `foo`.
let program_name = file_name
.strip_suffix(".leo")
.ok_or_else(PackageError::failed_to_get_file_name)?;
// If the program is an import, construct program name from file_path
// Otherwise, use the program_id found in `package.json`.
let program_name = match is_import {
false => program_id.name().to_string(),
true => file_name
.strip_suffix(".leo")
.ok_or_else(PackageError::failed_to_get_file_name)?
.to_string(),
};
// Create the path to the Aleo file.
let mut aleo_file_path = build.to_path_buf();
aleo_file_path.push(match is_import {
true => format!("{}.{}", program_name, program_id.network()),
false => format!("main.{}", program_id.network()),
});
// Create a new instance of the Leo compiler.
let mut compiler = Compiler::new(
program_name.to_string(),
program_name,
program_id.network().to_string(),
handler,
file_path.clone(),
outputs.to_path_buf(),
Some(options.into()),
is_import,
);
// TODO: Temporarily removing checksum files. Need to redesign this scheme.
// // Check if we need to compile the Leo program.
// let checksum_differs = {
// // Compute the current program checksum.
// let program_checksum = program.checksum()?;
//
// // Get the current program checksum.
// let checksum_file = ChecksumFile::new(program_name);
//
// // If a checksum file exists, check if it differs from the new checksum.
// let checksum_differs = if checksum_file.exists_at(package_path) {
// let previous_checksum = checksum_file.read_from(package_path)?;
// program_checksum != previous_checksum
// } else {
// // By default, the checksum differs if there is no checksum to compare against.
// true
// };
//
// // If checksum differs, compile the program
// if checksum_differs {
// // Write the new checksum to the output directory
// checksum_file.write_to(package_path, program_checksum)?;
//
// tracing::debug!("Checksum saved ({:?})", package_path);
// }
//
// checksum_differs
// };
// if checksum_differs {
// Compile the Leo program into Aleo instructions.
let (symbol_table, instructions) = compiler.compile_and_generate_instructions()?;
// Create the path to the Aleo file.
let mut aleo_file_path = build.to_path_buf();
aleo_file_path.push(format!("{}.aleo", program_name));
// Write the instructions.
std::fs::File::create(&aleo_file_path)
.map_err(CliError::failed_to_load_instructions)?

View File

@ -80,7 +80,6 @@ fn new_compiler(handler: &Handler) -> Compiler<'_> {
PathBuf::from(String::new()),
PathBuf::from(String::new()),
None,
false,
)
}