Add Annotation to AST; enable parser support

This commit is contained in:
Pranav Gaddamadugu 2022-08-04 15:10:30 -07:00
parent a269e0f764
commit 2b3bda7da7
8 changed files with 66 additions and 1 deletions

View File

@ -0,0 +1,29 @@
// 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;
use leo_span::Span;
use serde::{Deserialize, Serialize};
/// An annotation, e.g. @program.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Annotation {
/// The name of the annotation.
pub name: Identifier,
/// The span associated with the annotation.
pub span: Span,
}

View File

@ -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::{Block, FunctionInput, Identifier, Node, Type};
use crate::{Annotation, Block, FunctionInput, Identifier, Node, Type};
use leo_span::{sym, Span, Symbol};
use serde::{Deserialize, Serialize};
@ -24,6 +24,8 @@ use std::fmt;
/// A function definition.
#[derive(Clone, Serialize, Deserialize)]
pub struct Function {
/// Annotations on the function.
pub annotations: Vec<Annotation>,
/// The function identifier, e.g., `foo` in `function foo(...) { ... }`.
pub identifier: Identifier,
/// The function's parameters.

View File

@ -14,6 +14,9 @@
// 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/>.
pub mod annotation;
pub use annotation::*;
pub mod function;
pub use function::*;

View File

@ -280,6 +280,7 @@ pub trait ProgramReconstructor: StatementReconstructor {
fn reconstruct_function(&mut self, input: Function) -> Function {
Function {
annotations: input.annotations,
identifier: input.identifier,
input: input.input,
output: input.output,

View File

@ -270,9 +270,29 @@ impl ParserContext<'_> {
)
}
/// Returns an [`Annotation`] AST node if the next tokens represent an annotation.
fn parse_annotation(&mut self) -> Result<Annotation> {
// Parse the `@` symbol and identifier.
let start = self.expect(&Token::At)?;
let name = self.expect_identifier()?;
let span = start + name.span;
// TODO: Verify that this check is sound.
// Check that there is no whitespace in between the `@` symbol and identifier.
match name.span.hi.0 - start.lo.0 > 1 + name.name.as_str().len() as u32 {
true => Err(ParserError::space_in_annotation(span).into()),
false => Ok(Annotation { name, span }),
}
}
/// Returns an [`(Identifier, Function)`] AST node if the next tokens represent a function name
/// and function definition.
fn parse_function(&mut self) -> Result<(Identifier, Function)> {
// Parse annotations, if they exist.
let mut annotations = Vec::new();
while self.look_ahead(0, |t| &t.token) == &Token::At {
annotations.push(self.parse_annotation()?)
}
// Parse `function IDENT`.
let start = self.expect(&Token::Function)?;
let name = self.expect_identifier()?;
@ -292,6 +312,7 @@ impl ParserContext<'_> {
Ok((
name,
Function {
annotations,
identifier: name,
input: inputs,
output,

View File

@ -34,6 +34,7 @@ impl ProgramReconstructor for Unroller<'_> {
// Reconstruct the function block.
let reconstructed_function = Function {
annotations: function.annotations,
identifier: function.identifier,
input: function.input,
output: function.output,

View File

@ -96,6 +96,7 @@ impl ProgramReconstructor for StaticSingleAssigner<'_> {
self.pop();
Function {
annotations: function.annotations,
identifier: function.identifier,
input: function.input,
output: function.output,

View File

@ -253,4 +253,11 @@ create_messages!(
msg: format!("Invalid import call to non-leo file `{name}`."),
help: Some("Only imports of Leo `.leo` files are currently supported.".to_string()),
}
@formatted
space_in_annotation {
args: (),
msg: "Illegal spacing in the annotation declaration.",
help: Some("Remove whitespace between the `@` symbol and the identifier.".to_string()),
}
);