mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-27 12:17:35 +03:00
Update AST to include FunctionStub and Stub
This commit is contained in:
parent
72cf2e7517
commit
cf7baa0132
@ -59,6 +59,10 @@ pub mod types;
|
||||
pub use self::types::*;
|
||||
|
||||
pub mod value;
|
||||
|
||||
pub mod stub;
|
||||
pub use self::stub::*;
|
||||
|
||||
pub use self::value::*;
|
||||
|
||||
pub use common::node::*;
|
||||
|
@ -417,6 +417,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
|
||||
.into_iter()
|
||||
.map(|(id, import)| (id, (self.reconstruct_import(import.0), import.1)))
|
||||
.collect(),
|
||||
stubs: input.stubs,
|
||||
program_scopes: input
|
||||
.program_scopes
|
||||
.into_iter()
|
||||
|
@ -222,7 +222,7 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
||||
pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
|
||||
fn visit_program(&mut self, input: &'a Program) {
|
||||
input.imports.values().for_each(|import| self.visit_import(&import.0));
|
||||
|
||||
input.stubs.values().for_each(|stub| self.visit_stub(stub));
|
||||
input.program_scopes.values().for_each(|scope| self.visit_program_scope(scope));
|
||||
}
|
||||
|
||||
@ -236,6 +236,8 @@ pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
|
||||
input.consts.iter().for_each(|(_, c)| (self.visit_const(c)));
|
||||
}
|
||||
|
||||
fn visit_stub(&mut self, _input: &'a Stub) {}
|
||||
|
||||
fn visit_import(&mut self, input: &'a Program) {
|
||||
self.visit_program(input)
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ pub use program_scope::*;
|
||||
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
use crate::Stub;
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
@ -33,6 +34,8 @@ use std::fmt;
|
||||
pub struct Program {
|
||||
/// A map from import names to import definitions.
|
||||
pub imports: IndexMap<Symbol, (Program, Span)>,
|
||||
/// A map from program stub names to program stub scopes.
|
||||
pub stubs: IndexMap<Symbol, Stub>,
|
||||
/// A map from program names to program scopes.
|
||||
pub program_scopes: IndexMap<Symbol, ProgramScope>,
|
||||
}
|
||||
@ -42,6 +45,10 @@ impl fmt::Display for Program {
|
||||
for (id, _import) in self.imports.iter() {
|
||||
writeln!(f, "import {id}.leo;")?;
|
||||
}
|
||||
for (_, stub) in self.stubs.iter() {
|
||||
stub.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
}
|
||||
for (_, program_scope) in self.program_scopes.iter() {
|
||||
program_scope.fmt(f)?;
|
||||
writeln!(f,)?;
|
||||
@ -53,6 +60,6 @@ impl fmt::Display for Program {
|
||||
impl Default for Program {
|
||||
/// Constructs an empty program node.
|
||||
fn default() -> Self {
|
||||
Self { imports: IndexMap::new(), program_scopes: IndexMap::new() }
|
||||
Self { imports: IndexMap::new(), stubs: IndexMap::new(), program_scopes: IndexMap::new() }
|
||||
}
|
||||
}
|
||||
|
152
compiler/ast/src/stub/function_stub.rs
Normal file
152
compiler/ast/src/stub/function_stub.rs
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright (C) 2019-2023 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::{Annotation, Block, Finalize, Function, Identifier, Input, Node, NodeID, Output, Tuple, Type, Variant};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A function stub definition.
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct FunctionStub {
|
||||
/// Annotations on the function.
|
||||
pub annotations: Vec<Annotation>,
|
||||
/// Is this function a transition, inlined, or a regular function?.
|
||||
pub variant: Variant,
|
||||
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
|
||||
pub identifier: Identifier,
|
||||
/// The function's input parameters.
|
||||
pub input: Vec<Input>,
|
||||
/// The function's output declarations.
|
||||
pub output: Vec<Output>,
|
||||
/// The function's output type.
|
||||
pub output_type: Type,
|
||||
/// The body of the function.
|
||||
pub block: Block,
|
||||
/// An optional finalize block
|
||||
pub finalize: Option<Finalize>,
|
||||
/// The entire span of the function definition.
|
||||
pub span: Span,
|
||||
/// The ID of the node.
|
||||
pub id: NodeID,
|
||||
}
|
||||
|
||||
impl PartialEq for FunctionStub {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.identifier == other.identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FunctionStub {}
|
||||
|
||||
impl FunctionStub {
|
||||
/// Initialize a new function.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
annotations: Vec<Annotation>,
|
||||
variant: Variant,
|
||||
identifier: Identifier,
|
||||
input: Vec<Input>,
|
||||
output: Vec<Output>,
|
||||
block: Block,
|
||||
finalize: Option<Finalize>,
|
||||
span: Span,
|
||||
id: NodeID,
|
||||
) -> Self {
|
||||
// Determine the output type of the function
|
||||
let get_output_type = |output: &Output| match &output {
|
||||
Output::Internal(output) => output.type_.clone(),
|
||||
Output::External(output) => output.type_(),
|
||||
};
|
||||
|
||||
let output_type = match output.len() {
|
||||
0 => Type::Unit,
|
||||
1 => get_output_type(&output[0]),
|
||||
_ => Type::Tuple(Tuple(output.iter().map(get_output_type).collect())),
|
||||
};
|
||||
|
||||
FunctionStub { annotations, variant, identifier, input, output, output_type, block, finalize, span, id }
|
||||
}
|
||||
|
||||
/// Returns function name.
|
||||
pub fn name(&self) -> Symbol {
|
||||
self.identifier.name
|
||||
}
|
||||
|
||||
/// Returns `true` if the function name is `main`.
|
||||
pub fn is_main(&self) -> bool {
|
||||
self.name() == sym::main
|
||||
}
|
||||
|
||||
///
|
||||
/// Private formatting method used for optimizing [fmt::Debug] and [fmt::Display] implementations.
|
||||
///
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.variant {
|
||||
Variant::Inline => write!(f, "inline ")?,
|
||||
Variant::Standard => write!(f, "function ")?,
|
||||
Variant::Transition => write!(f, "transition ")?,
|
||||
}
|
||||
write!(f, "{}", self.identifier)?;
|
||||
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
let returns = match self.output.len() {
|
||||
0 => "()".to_string(),
|
||||
1 => self.output[0].to_string(),
|
||||
_ => self.output.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","),
|
||||
};
|
||||
write!(f, "({parameters}) -> {returns} {}", self.block)?;
|
||||
|
||||
if let Some(finalize) = &self.finalize {
|
||||
let parameters = finalize.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
write!(f, " finalize ({parameters}) {}", finalize.block)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Function> for FunctionStub {
|
||||
fn from(function: Function) -> Self {
|
||||
Self {
|
||||
annotations: function.annotations,
|
||||
variant: function.variant,
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
output_type: function.output_type,
|
||||
block: function.block,
|
||||
finalize: function.finalize,
|
||||
span: function.span,
|
||||
id: function.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FunctionStub {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FunctionStub {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(FunctionStub);
|
75
compiler/ast/src/stub/mod.rs
Normal file
75
compiler/ast/src/stub/mod.rs
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2019-2023 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/>.
|
||||
|
||||
//! A stub contains function templates as well as definitions for mappings, structs, records, and constants.
|
||||
|
||||
pub mod function_stub;
|
||||
pub use function_stub::*;
|
||||
|
||||
use crate::{ConstDeclaration, Mapping, ProgramId, ProgramScope, Struct};
|
||||
use leo_span::{Span, Symbol};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// Stores the Leo stub abstract syntax tree.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Stub {
|
||||
/// The stub id
|
||||
pub stub_id: ProgramId,
|
||||
/// A vector of const definitions
|
||||
pub consts: Vec<(Symbol, ConstDeclaration)>,
|
||||
/// A vector of struct definitions.
|
||||
pub structs: Vec<(Symbol, Struct)>,
|
||||
/// A vector of mapping definitions.
|
||||
pub mappings: Vec<(Symbol, Mapping)>,
|
||||
/// A vector of function stub definitions.
|
||||
pub functions: Vec<(Symbol, FunctionStub)>,
|
||||
/// The span associated with the stub.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl From<ProgramScope> for Stub {
|
||||
fn from(program_scope: ProgramScope) -> Self {
|
||||
Self {
|
||||
stub_id: program_scope.program_id,
|
||||
consts: program_scope.consts,
|
||||
structs: program_scope.structs,
|
||||
mappings: program_scope.mappings,
|
||||
functions: program_scope
|
||||
.functions
|
||||
.into_iter()
|
||||
.map(|(symbol, function)| (symbol, FunctionStub::from(function)))
|
||||
.collect(),
|
||||
span: program_scope.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Stub {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "stub {} {{", self.stub_id)?;
|
||||
for (_, struct_) in self.structs.iter() {
|
||||
writeln!(f, " {struct_}")?;
|
||||
}
|
||||
for (_, mapping) in self.mappings.iter() {
|
||||
writeln!(f, " {mapping}")?;
|
||||
}
|
||||
for (_, function) in self.functions.iter() {
|
||||
writeln!(f, " {function}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -151,6 +151,7 @@ impl ProgramConsumer for StaticSingleAssigner<'_> {
|
||||
.into_iter()
|
||||
.map(|(name, (import, span))| (name, (self.consume_program(import), span)))
|
||||
.collect(),
|
||||
stubs: input.stubs,
|
||||
program_scopes: input
|
||||
.program_scopes
|
||||
.into_iter()
|
||||
|
Loading…
Reference in New Issue
Block a user