mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-23 23:23:50 +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 use self::types::*;
|
||||||
|
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
|
pub mod stub;
|
||||||
|
pub use self::stub::*;
|
||||||
|
|
||||||
pub use self::value::*;
|
pub use self::value::*;
|
||||||
|
|
||||||
pub use common::node::*;
|
pub use common::node::*;
|
||||||
|
@ -417,6 +417,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(id, import)| (id, (self.reconstruct_import(import.0), import.1)))
|
.map(|(id, import)| (id, (self.reconstruct_import(import.0), import.1)))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
stubs: input.stubs,
|
||||||
program_scopes: input
|
program_scopes: input
|
||||||
.program_scopes
|
.program_scopes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -222,7 +222,7 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
|||||||
pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
|
pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
|
||||||
fn visit_program(&mut self, input: &'a Program) {
|
fn visit_program(&mut self, input: &'a Program) {
|
||||||
input.imports.values().for_each(|import| self.visit_import(&import.0));
|
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));
|
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)));
|
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) {
|
fn visit_import(&mut self, input: &'a Program) {
|
||||||
self.visit_program(input)
|
self.visit_program(input)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ pub use program_scope::*;
|
|||||||
|
|
||||||
use leo_span::{Span, Symbol};
|
use leo_span::{Span, Symbol};
|
||||||
|
|
||||||
|
use crate::Stub;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -33,6 +34,8 @@ use std::fmt;
|
|||||||
pub struct Program {
|
pub struct Program {
|
||||||
/// A map from import names to import definitions.
|
/// A map from import names to import definitions.
|
||||||
pub imports: IndexMap<Symbol, (Program, Span)>,
|
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.
|
/// A map from program names to program scopes.
|
||||||
pub program_scopes: IndexMap<Symbol, ProgramScope>,
|
pub program_scopes: IndexMap<Symbol, ProgramScope>,
|
||||||
}
|
}
|
||||||
@ -42,6 +45,10 @@ impl fmt::Display for Program {
|
|||||||
for (id, _import) in self.imports.iter() {
|
for (id, _import) in self.imports.iter() {
|
||||||
writeln!(f, "import {id}.leo;")?;
|
writeln!(f, "import {id}.leo;")?;
|
||||||
}
|
}
|
||||||
|
for (_, stub) in self.stubs.iter() {
|
||||||
|
stub.fmt(f)?;
|
||||||
|
writeln!(f,)?;
|
||||||
|
}
|
||||||
for (_, program_scope) in self.program_scopes.iter() {
|
for (_, program_scope) in self.program_scopes.iter() {
|
||||||
program_scope.fmt(f)?;
|
program_scope.fmt(f)?;
|
||||||
writeln!(f,)?;
|
writeln!(f,)?;
|
||||||
@ -53,6 +60,6 @@ impl fmt::Display for Program {
|
|||||||
impl Default for Program {
|
impl Default for Program {
|
||||||
/// Constructs an empty program node.
|
/// Constructs an empty program node.
|
||||||
fn default() -> Self {
|
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()
|
.into_iter()
|
||||||
.map(|(name, (import, span))| (name, (self.consume_program(import), span)))
|
.map(|(name, (import, span))| (name, (self.consume_program(import), span)))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
stubs: input.stubs,
|
||||||
program_scopes: input
|
program_scopes: input
|
||||||
.program_scopes
|
.program_scopes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
Loading…
Reference in New Issue
Block a user