mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 19:22:01 +03:00
Add finalize block to AST
This commit is contained in:
parent
75307d1d4e
commit
5521e7f30b
45
compiler/ast/src/functions/finalize.rs
Normal file
45
compiler/ast/src/functions/finalize.rs
Normal file
@ -0,0 +1,45 @@
|
||||
// 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::{Block, FunctionInput, Node, Type};
|
||||
|
||||
use leo_span::Span;
|
||||
|
||||
use core::fmt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A finalize block.
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Debug)]
|
||||
pub struct Finalize {
|
||||
/// The finalize block's input parameters.
|
||||
pub input: Vec<FunctionInput>,
|
||||
/// The finalize blocks's return type.
|
||||
pub output: Type,
|
||||
/// The body of the function.
|
||||
pub block: Block,
|
||||
/// The entire span of the finalize block.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for Finalize {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, " finalize")?;
|
||||
let parameters = self.input.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(",");
|
||||
write!(f, "({}) -> {} {}", parameters, self.output, self.block)
|
||||
}
|
||||
}
|
||||
|
||||
crate::simple_node_impl!(Finalize);
|
@ -17,6 +17,9 @@
|
||||
pub mod annotation;
|
||||
pub use annotation::*;
|
||||
|
||||
pub mod finalize;
|
||||
pub use finalize::*;
|
||||
|
||||
pub mod function_input;
|
||||
pub use function_input::*;
|
||||
|
||||
@ -24,7 +27,6 @@ use crate::{Block, Identifier, Node, Type};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
|
||||
/// A function definition.
|
||||
@ -38,11 +40,10 @@ pub struct Function {
|
||||
pub input: Vec<FunctionInput>,
|
||||
/// The function's required return type.
|
||||
pub output: Type,
|
||||
/// Any mapping to the core library.
|
||||
/// Always `None` when initially parsed.
|
||||
pub core_mapping: Cell<Option<Symbol>>,
|
||||
/// 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,
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
extern crate core;
|
||||
|
||||
pub mod access;
|
||||
pub use self::access::*;
|
||||
|
||||
|
@ -278,8 +278,13 @@ pub trait ProgramReconstructor: StatementReconstructor {
|
||||
identifier: input.identifier,
|
||||
input: input.input,
|
||||
output: input.output,
|
||||
core_mapping: input.core_mapping,
|
||||
block: self.reconstruct_block(input.block),
|
||||
finalize: input.finalize.map(|finalize| Finalize {
|
||||
input: finalize.input,
|
||||
output: finalize.output,
|
||||
block: self.reconstruct_block(finalize.block),
|
||||
span: finalize.span,
|
||||
}),
|
||||
span: input.span,
|
||||
}
|
||||
}
|
||||
|
@ -193,6 +193,9 @@ pub trait ProgramVisitor<'a>: StatementVisitor<'a> {
|
||||
|
||||
fn visit_function(&mut self, input: &'a Function) {
|
||||
self.visit_block(&input.block);
|
||||
if let Some(finalize) = &input.finalize {
|
||||
self.visit_block(&finalize.block);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_circuit(&mut self, _input: &'a Circuit) {}
|
||||
|
@ -43,6 +43,8 @@ pub enum Type {
|
||||
String,
|
||||
/// A static tuple of at least one type.
|
||||
Tuple(Tuple),
|
||||
/// The `unit` type.
|
||||
Unit,
|
||||
/// Placeholder for a type that could not be resolved or was not well-formed.
|
||||
/// Will eventually lead to a compile error.
|
||||
Err,
|
||||
@ -61,7 +63,8 @@ impl Type {
|
||||
| (Type::Field, Type::Field)
|
||||
| (Type::Group, Type::Group)
|
||||
| (Type::Scalar, Type::Scalar)
|
||||
| (Type::String, Type::String) => true,
|
||||
| (Type::String, Type::String)
|
||||
| (Type::Unit, Type::Unit) => true,
|
||||
(Type::Integer(left), Type::Integer(right)) => left.eq(right),
|
||||
(Type::Mapping(left), Type::Mapping(right)) => {
|
||||
left.key.eq_flat(&right.key) && left.value.eq_flat(&right.value)
|
||||
@ -89,6 +92,7 @@ impl fmt::Display for Type {
|
||||
Type::Scalar => write!(f, "scalar"),
|
||||
Type::String => write!(f, "string"),
|
||||
Type::Tuple(ref tuple) => write!(f, "{}", tuple),
|
||||
Type::Unit => write!(f, "()"),
|
||||
Type::Err => write!(f, "error"),
|
||||
}
|
||||
}
|
||||
|
@ -349,8 +349,8 @@ impl ParserContext<'_> {
|
||||
input: inputs,
|
||||
output,
|
||||
span: start + block.span,
|
||||
finalize: None,
|
||||
block,
|
||||
core_mapping: <_>::default(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -402,6 +402,7 @@ impl Token {
|
||||
"else" => Token::Else,
|
||||
"false" => Token::False,
|
||||
"field" => Token::Field,
|
||||
"finalize" => Token::Finalize,
|
||||
"for" => Token::For,
|
||||
"function" => Token::Function,
|
||||
"group" => Token::Group,
|
||||
|
@ -88,6 +88,7 @@ mod tests {
|
||||
else
|
||||
false
|
||||
field
|
||||
finalize
|
||||
for
|
||||
function
|
||||
group
|
||||
@ -155,7 +156,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
output,
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address bool const else false field for function group i128 i64 i32 i16 i8 if in input let mut return scalar string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> => _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
|
||||
r#""test" "test{}test" "test{}" "{}test" "test{" "test}" "test{test" "test}test" "te{{}}" test_ident 12345 address bool const else false field finalize for function group i128 i64 i32 i16 i8 if in input let mut return scalar string test true u128 u64 u32 u16 u8 console ! != && ( ) * ** + , - -> => _ . .. / : ; < <= = == > >= [ ] { { } } || ? @ // test
|
||||
/* test */ // "#
|
||||
);
|
||||
});
|
||||
|
@ -115,6 +115,7 @@ pub enum Token {
|
||||
// Constant parameter
|
||||
Constant,
|
||||
Else,
|
||||
Finalize,
|
||||
For,
|
||||
Function,
|
||||
If,
|
||||
@ -146,6 +147,7 @@ pub const KEYWORD_TOKENS: &[Token] = &[
|
||||
Token::Else,
|
||||
Token::False,
|
||||
Token::Field,
|
||||
Token::Finalize,
|
||||
Token::For,
|
||||
Token::Function,
|
||||
Token::Group,
|
||||
@ -192,6 +194,7 @@ impl Token {
|
||||
Token::Else => sym::Else,
|
||||
Token::False => sym::False,
|
||||
Token::Field => sym::field,
|
||||
Token::Finalize => sym::finalize,
|
||||
Token::For => sym::For,
|
||||
Token::Function => sym::function,
|
||||
Token::Group => sym::group,
|
||||
@ -312,6 +315,7 @@ impl fmt::Display for Token {
|
||||
Const => write!(f, "const"),
|
||||
Constant => write!(f, "constant"),
|
||||
Else => write!(f, "else"),
|
||||
Finalize => write!(f, "finalize"),
|
||||
For => write!(f, "for"),
|
||||
Function => write!(f, "function"),
|
||||
If => write!(f, "if"),
|
||||
|
@ -43,6 +43,7 @@ impl<'a> CodeGenerator<'a> {
|
||||
unreachable!("Tuple types are not supported at this phase of compilation")
|
||||
}
|
||||
Type::Err => unreachable!("Error types should not exist at this phase of compilation"),
|
||||
Type::Unit => unreachable!("Unit types are not supported at this phase of compilation"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,8 @@ impl ProgramReconstructor for Unroller<'_> {
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
core_mapping: function.core_mapping,
|
||||
block: self.reconstruct_block(function.block),
|
||||
finalize: function.finalize,
|
||||
span: function.span,
|
||||
};
|
||||
|
||||
|
@ -141,11 +141,11 @@ impl FunctionConsumer for StaticSingleAssigner<'_> {
|
||||
identifier: function.identifier,
|
||||
input: function.input,
|
||||
output: function.output,
|
||||
core_mapping: function.core_mapping,
|
||||
block: Block {
|
||||
span: Default::default(),
|
||||
statements,
|
||||
},
|
||||
finalize: function.finalize,
|
||||
span: function.span,
|
||||
}
|
||||
}
|
||||
|
@ -187,6 +187,7 @@ symbols! {
|
||||
CoreFunction,
|
||||
console,
|
||||
Else: "else",
|
||||
finalize,
|
||||
For: "for",
|
||||
function,
|
||||
If: "if",
|
||||
|
Loading…
Reference in New Issue
Block a user