Nest annotated declarations within the annotation ast node

This commit is contained in:
Greg Shuflin 2021-11-02 14:40:28 -07:00
parent 0464d959ec
commit 9de1b4ea33
3 changed files with 37 additions and 18 deletions

View File

@ -130,7 +130,7 @@ pub enum Declaration {
Binding { name: Rc<String>, constant: bool, type_anno: Option<TypeIdentifier>, expr: Expression },
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
Interface { name: Rc<String>, signatures: Vec<Signature> },
Annotation { name: Rc<String>, arguments: Vec<Expression> },
Annotation { name: Rc<String>, arguments: Vec<Expression>, inner: Box<Declaration> },
}
#[derive(Debug, PartialEq, Clone)]

View File

@ -17,7 +17,8 @@
//! delimiter := NEWLINE | ";"
//! statement := expression | declaration | import | module | flow
//! block := "{" (statement delimiter)* "}"
//! declaration := type_declaration | func_declaration | binding_declaration | impl_declaration
//! declaration := annotation? declaration | bare_declaration
//! bare_declaration := type_declaration | func_declaration | binding_declaration | impl_declaration
//! ```
//! ## Declarations
//!
@ -393,22 +394,30 @@ impl Parser {
//TODO handle error recovery here
let tok = self.token_handler.peek();
let kind = match tok.get_kind() {
AtSign => self.annotation().map(StatementKind::Declaration),
Keyword(Type) => self.type_declaration().map(StatementKind::Declaration),
Keyword(Func) => self.func_declaration().map(StatementKind::Declaration),
Keyword(Let) => self.binding_declaration().map(StatementKind::Declaration),
Keyword(Interface) => self.interface_declaration().map(StatementKind::Declaration),
Keyword(Impl) => self.impl_declaration().map(StatementKind::Declaration),
Keyword(Import) => self.import_declaration().map(StatementKind::Import),
Keyword(Module) => self.module_declaration().map(StatementKind::Module),
AtSign | Keyword(Let) | Keyword(Type) | Keyword(Func) | Keyword(Interface) | Keyword(Impl) =>
self.declaration().map(StatementKind::Declaration),
Keyword(Continue) | Keyword(Return) | Keyword(Break) =>
self.flow_control().map(StatementKind::Flow),
Keyword(Import) => self.import_declaration().map(StatementKind::Import),
Keyword(Module) => self.module_declaration().map(StatementKind::Module),
_ => self.expression().map(StatementKind::Expression),
}?;
let id = self.id_store.fresh();
Ok(Statement { kind, id, location: tok.location })
}
fn declaration(&mut self) -> ParseResult<Declaration> {
match self.token_handler.peek_kind() {
AtSign => self.annotation(),
Keyword(Let) => self.binding_declaration(),
Keyword(Type) => self.type_declaration(),
Keyword(Func) => self.func_declaration(),
Keyword(Interface) => self.interface_declaration(),
Keyword(Impl) => self.impl_declaration(),
_ => return ParseError::new_with_token("Bad parse state encountered", self.token_handler.peek()),
}
}
#[recursive_descent_method]
fn flow_control(&mut self) -> ParseResult<FlowControl> {
let tok = self.token_handler.next();
@ -423,6 +432,7 @@ impl Parser {
})
}
//TODO make it possible to annotate other types of things
#[recursive_descent_method]
fn annotation(&mut self) -> ParseResult<Declaration> {
expect!(self, AtSign);
@ -432,8 +442,11 @@ impl Parser {
} else {
vec![]
};
Ok(Declaration::Annotation { name, arguments })
if let Semicolon | Newline = self.token_handler.peek_kind() {
self.token_handler.next();
}
let inner = Box::new(self.declaration()?);
Ok(Declaration::Annotation { name, arguments, inner })
}
#[recursive_descent_method]

View File

@ -928,6 +928,11 @@ fn impls() {
fn annotations() {
use ExpressionKind::*;
let func = Declaration::FuncDecl(
Signature { name: rc("some_function"), operator: false, params: vec![], type_anno: None },
vec![].into(),
);
assert_ast! {
r#"
@test_annotation
@ -936,25 +941,26 @@ fn annotations() {
}"#,
vec![decl(Declaration::Annotation {
name: rc("test_annotation"),
arguments: vec![]
arguments: vec![],
inner: bx(func.clone()),
}),
fn_decl(Signature { name: rc("some_function"), operator: false, params: vec![], type_anno: None },
vec![].into())
]
};
assert_ast! {
r#"
@test_annotation(some,value)
@another_annotation
fn some_function() {
}"#,
vec![decl(Declaration::Annotation {
name: rc("test_annotation"),
arguments: vec![expr(Value(qn!(some))), expr(Value(qn!(value)))]
arguments: vec![expr(Value(qn!(some))), expr(Value(qn!(value)))],
inner: bx(Declaration::Annotation {
name: rc("another_annotation"), arguments: vec![], inner: bx(func)
})
}),
fn_decl(Signature { name: rc("some_function"), operator: false, params: vec![], type_anno: None },
vec![].into())
]
};
}