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 }, Binding { name: Rc<String>, constant: bool, type_anno: Option<TypeIdentifier>, expr: Expression },
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> }, Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
Interface { name: Rc<String>, signatures: Vec<Signature> }, 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)] #[derive(Debug, PartialEq, Clone)]

View File

@ -17,7 +17,8 @@
//! delimiter := NEWLINE | ";" //! delimiter := NEWLINE | ";"
//! statement := expression | declaration | import | module | flow //! statement := expression | declaration | import | module | flow
//! block := "{" (statement delimiter)* "}" //! 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 //! ## Declarations
//! //!
@ -393,22 +394,30 @@ impl Parser {
//TODO handle error recovery here //TODO handle error recovery here
let tok = self.token_handler.peek(); let tok = self.token_handler.peek();
let kind = match tok.get_kind() { let kind = match tok.get_kind() {
AtSign => self.annotation().map(StatementKind::Declaration), AtSign | Keyword(Let) | Keyword(Type) | Keyword(Func) | Keyword(Interface) | Keyword(Impl) =>
Keyword(Type) => self.type_declaration().map(StatementKind::Declaration), self.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),
Keyword(Continue) | Keyword(Return) | Keyword(Break) => Keyword(Continue) | Keyword(Return) | Keyword(Break) =>
self.flow_control().map(StatementKind::Flow), 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), _ => self.expression().map(StatementKind::Expression),
}?; }?;
let id = self.id_store.fresh(); let id = self.id_store.fresh();
Ok(Statement { kind, id, location: tok.location }) 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] #[recursive_descent_method]
fn flow_control(&mut self) -> ParseResult<FlowControl> { fn flow_control(&mut self) -> ParseResult<FlowControl> {
let tok = self.token_handler.next(); 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] #[recursive_descent_method]
fn annotation(&mut self) -> ParseResult<Declaration> { fn annotation(&mut self) -> ParseResult<Declaration> {
expect!(self, AtSign); expect!(self, AtSign);
@ -432,8 +442,11 @@ impl Parser {
} else { } else {
vec![] vec![]
}; };
if let Semicolon | Newline = self.token_handler.peek_kind() {
Ok(Declaration::Annotation { name, arguments }) self.token_handler.next();
}
let inner = Box::new(self.declaration()?);
Ok(Declaration::Annotation { name, arguments, inner })
} }
#[recursive_descent_method] #[recursive_descent_method]

View File

@ -928,6 +928,11 @@ fn impls() {
fn annotations() { fn annotations() {
use ExpressionKind::*; use ExpressionKind::*;
let func = Declaration::FuncDecl(
Signature { name: rc("some_function"), operator: false, params: vec![], type_anno: None },
vec![].into(),
);
assert_ast! { assert_ast! {
r#" r#"
@test_annotation @test_annotation
@ -936,25 +941,26 @@ fn annotations() {
}"#, }"#,
vec![decl(Declaration::Annotation { vec![decl(Declaration::Annotation {
name: rc("test_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! { assert_ast! {
r#" r#"
@test_annotation(some,value) @test_annotation(some,value)
@another_annotation
fn some_function() { fn some_function() {
}"#, }"#,
vec![decl(Declaration::Annotation { vec![decl(Declaration::Annotation {
name: rc("test_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())
] ]
}; };
} }