mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-13 08:47:17 +03:00
wip need to finish external inputs
This commit is contained in:
parent
368d4c530c
commit
48530523d9
46
compiler/ast/src/functions/external.rs
Normal file
46
compiler/ast/src/functions/external.rs
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Mode, Node, Type};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A function output from an external program with type record.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct External {
|
||||
/// The name of the external program.
|
||||
pub external: Identifier,
|
||||
/// The name of the external record type.
|
||||
pub record: Identifier,
|
||||
/// The parameters span from any annotations to its type.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl External {
|
||||
pub fn get_type(&self) -> Type {
|
||||
Type::Identifier(self.record.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for External {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.leo/{}.record", self.external, self.record)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(FunctionOutputExternal);
|
@ -14,14 +14,48 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Mode, Node, Type};
|
||||
use crate::{External, Identifier, Mode, Node, Type};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Input {
|
||||
Internal(FunctionInput),
|
||||
External(External),
|
||||
}
|
||||
|
||||
impl fmt::Display for Input {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use Input::*;
|
||||
match self {
|
||||
Internal(input) => input.fmt(f),
|
||||
External(input) => input.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for Input {
|
||||
fn span(&self) -> Span {
|
||||
use Input::*;
|
||||
match self {
|
||||
Internal(input) => input.span(),
|
||||
External(input) => input.span(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_span(&mut self, span: Span) {
|
||||
use Input::*;
|
||||
match self {
|
||||
Internal(input) => input.set_span(span),
|
||||
External(input) => input.set_span(span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A function parameter.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FunctionInput {
|
||||
/// The name the parameter is accessible as in the function's body.
|
||||
pub identifier: Identifier,
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Identifier, Mode, Node, Type};
|
||||
use crate::{External, Identifier, Mode, Node, Type};
|
||||
use leo_span::Span;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -23,7 +23,7 @@ use std::fmt;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Output {
|
||||
Internal(FunctionOutput),
|
||||
External(FunctionOutputExternal),
|
||||
External(External),
|
||||
}
|
||||
|
||||
impl fmt::Display for Output {
|
||||
@ -72,28 +72,3 @@ impl fmt::Display for FunctionOutput {
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(FunctionOutput);
|
||||
|
||||
/// A function output from an external program with type record.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FunctionOutputExternal {
|
||||
/// The name of the external program.
|
||||
pub external: Identifier,
|
||||
/// The name of the external record type.
|
||||
pub record: Identifier,
|
||||
/// The parameters span from any annotations to its type.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl FunctionOutputExternal {
|
||||
pub fn get_type(&self) -> Type {
|
||||
Type::Identifier(self.record.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FunctionOutputExternal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}.leo/{}.record", self.external, self.record)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(FunctionOutputExternal);
|
||||
|
@ -17,6 +17,9 @@
|
||||
pub mod annotation;
|
||||
pub use annotation::*;
|
||||
|
||||
pub mod external;
|
||||
pub use external::*;
|
||||
|
||||
pub mod finalize;
|
||||
pub use finalize::*;
|
||||
|
||||
@ -43,7 +46,7 @@ pub struct Function {
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
pub identifier: Identifier,
|
||||
/// The function's input parameters.
|
||||
pub input: Vec<FunctionInput>,
|
||||
pub input: Vec<Input>,
|
||||
/// The function's output declarations.
|
||||
pub output: Vec<Output>,
|
||||
/// The function's output type.
|
||||
@ -69,7 +72,7 @@ impl Function {
|
||||
pub fn new(
|
||||
annotations: Vec<Annotation>,
|
||||
identifier: Identifier,
|
||||
input: Vec<FunctionInput>,
|
||||
input: Vec<Input>,
|
||||
output: Vec<Output>,
|
||||
block: Block,
|
||||
finalize: Option<Finalize>,
|
||||
|
@ -363,7 +363,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
|
||||
}
|
||||
|
||||
fn reconstruct_import(&mut self, input: Program) -> Program {
|
||||
input
|
||||
self.reconstruct_program(input)
|
||||
}
|
||||
|
||||
fn reconstruct_mapping(&mut self, input: Mapping) -> Mapping {
|
||||
|
@ -295,6 +295,31 @@ impl ParserContext<'_> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a [`Input`] AST node if the next tokens represent a function output.
|
||||
fn parse_input(&mut self) -> Result<functions::Input> {
|
||||
if self.peek_is_external() {
|
||||
let external = self.expect_identifier()?;
|
||||
let mut span = external.span;
|
||||
|
||||
// Parse `.leo/`.
|
||||
self.eat(&Token::Dot);
|
||||
self.eat(&Token::Leo);
|
||||
self.eat(&Token::Div);
|
||||
|
||||
// Parse record name.
|
||||
let record = self.expect_identifier()?;
|
||||
|
||||
// Parse `.record`.
|
||||
self.eat(&Token::Dot);
|
||||
self.eat(&Token::Record);
|
||||
span = span + self.prev_token.span;
|
||||
|
||||
Ok(functions::Input::External(External { external, record, span }))
|
||||
} else {
|
||||
Ok(functions::Input::Internal(self.parse_function_input()?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a [`FunctionOutput`] AST node if the next tokens represent a function output.
|
||||
fn parse_function_output(&mut self) -> Result<FunctionOutput> {
|
||||
// TODO: Could this span be made more accurate?
|
||||
@ -303,7 +328,7 @@ impl ParserContext<'_> {
|
||||
Ok(FunctionOutput { mode, type_, span })
|
||||
}
|
||||
|
||||
/// Returns a [`FunctionOutput`] AST node if the next tokens represent a function output.
|
||||
/// Returns a [`Output`] AST node if the next tokens represent a function output.
|
||||
fn parse_output(&mut self) -> Result<Output> {
|
||||
if self.peek_is_external() {
|
||||
let external = self.expect_identifier()?;
|
||||
@ -322,7 +347,7 @@ impl ParserContext<'_> {
|
||||
self.eat(&Token::Record);
|
||||
span = span + self.prev_token.span;
|
||||
|
||||
Ok(Output::External(FunctionOutputExternal { external, record, span }))
|
||||
Ok(Output::External(External { external, record, span }))
|
||||
} else {
|
||||
Ok(Output::Internal(self.parse_function_output()?))
|
||||
}
|
||||
@ -374,7 +399,7 @@ impl ParserContext<'_> {
|
||||
let name = self.expect_identifier()?;
|
||||
|
||||
// Parse parameters.
|
||||
let (inputs, ..) = self.parse_paren_comma_list(|p| p.parse_function_input().map(Some))?;
|
||||
let (inputs, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?;
|
||||
|
||||
// Parse return type.
|
||||
let output = match self.eat(&Token::Arrow) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use crate::CodeGenerator;
|
||||
|
||||
use leo_ast::{Circuit, CircuitMember, Function, Identifier, Mapping, Mode, Program, Type};
|
||||
use leo_ast::{functions, Circuit, CircuitMember, Function, Identifier, Mapping, Mode, Program, Type};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use itertools::Itertools;
|
||||
@ -185,14 +185,22 @@ impl<'a> CodeGenerator<'a> {
|
||||
let register_string = format!("r{}", self.next_register);
|
||||
self.next_register += 1;
|
||||
|
||||
self.variable_mapping
|
||||
.insert(&input.identifier.name, register_string.clone());
|
||||
let type_string = match input {
|
||||
functions::Input::Internal(input) => {
|
||||
self.variable_mapping
|
||||
.insert(&input.identifier.name, register_string.clone());
|
||||
|
||||
let visibility = match (self.is_program_function, input.mode) {
|
||||
(true, Mode::None) => Mode::Private,
|
||||
_ => input.mode,
|
||||
let visibility = match (self.is_program_function, input.mode) {
|
||||
(true, Mode::None) => Mode::Private,
|
||||
_ => input.mode,
|
||||
};
|
||||
self.visit_type_with_visibility(&input.type_, visibility)
|
||||
}
|
||||
functions::Input::External(input) => {
|
||||
format!("{}.aleo/{}.record", input.external, input.record)
|
||||
}
|
||||
};
|
||||
let type_string = self.visit_type_with_visibility(&input.type_, visibility);
|
||||
|
||||
writeln!(function_string, " input {} as {};", register_string, type_string,)
|
||||
.expect("failed to write to string");
|
||||
}
|
||||
|
@ -92,7 +92,11 @@ impl ProgramConsumer for StaticSingleAssigner {
|
||||
network: input.network,
|
||||
expected_input: input.expected_input,
|
||||
// TODO: Do inputs need to be processed? They are not processed in the existing compiler.
|
||||
imports: input.imports,
|
||||
imports: input
|
||||
.imports
|
||||
.into_iter()
|
||||
.map(|(name, import)| (name, self.consume_program(import)))
|
||||
.collect(),
|
||||
functions: input
|
||||
.functions
|
||||
.into_iter()
|
||||
|
@ -16,7 +16,7 @@ function initialize_board(
|
||||
destroyer: u64,
|
||||
// The address of the opponent.
|
||||
player: address,
|
||||
) -> board_state {
|
||||
) -> 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);
|
||||
@ -31,10 +31,10 @@ function initialize_board(
|
||||
console.assert(valid_destroyer);
|
||||
|
||||
// Create the board with all the ship placements combined.
|
||||
let board: u64 = board.leo/create_board(carrier, battleship, cruiser, destroyer);
|
||||
let board: u64 = verify.leo/create_board(carrier, battleship, cruiser, destroyer);
|
||||
|
||||
// Initialize the board state record.
|
||||
let state: board_state = verify.leo/new_board_state(board, player);
|
||||
let state: board_state = board.leo/new_board_state(board, player);
|
||||
|
||||
return state;
|
||||
}
|
||||
@ -46,7 +46,7 @@ function initialize_board(
|
||||
function offer_battleship(
|
||||
// The board record to start a game with.
|
||||
board: board_state,
|
||||
) -> (board_state, move) {
|
||||
) -> (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);
|
||||
|
||||
@ -61,7 +61,7 @@ function start_battleship(
|
||||
board: board_state,
|
||||
// The move record to play to begin the game. This should be the dummy move record created from offer_battleship.
|
||||
move_start: move,
|
||||
) -> (board_state, move) {
|
||||
) -> (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_1);
|
||||
console.assert_eq(board.player_2, move_start.player_2);
|
||||
@ -82,7 +82,7 @@ function play(
|
||||
move_incoming: move,
|
||||
// The u64 equivalent of the bitwise representation of the next coordinate to play on the opponent's board.
|
||||
shoot: u64,
|
||||
) -> (board_state, move) {
|
||||
) -> (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);
|
||||
|
Loading…
Reference in New Issue
Block a user