Nest annotated declarations within the annotation ast node
This commit is contained in:
parent
0464d959ec
commit
9de1b4ea33
@ -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)]
|
||||||
|
@ -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]
|
||||||
|
@ -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())
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user