Add parsing for annotations
This commit is contained in:
parent
3b5ebf92b4
commit
248af74ec0
@ -114,9 +114,28 @@ pub enum Declaration {
|
||||
Interface {
|
||||
name: Rc<String>,
|
||||
signatures: Vec<Signature>
|
||||
},
|
||||
Annotation {
|
||||
name: Rc<String>,
|
||||
arguments: Vec<Expression>
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @foo(arg1, arg2)
|
||||
* fn hello() {
|
||||
*
|
||||
* }
|
||||
*
|
||||
* Declaration::Annotation {
|
||||
* name: "foo",
|
||||
* arguments: vec!["arg1", "arg2"]
|
||||
* }
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Signature {
|
||||
pub name: Rc<String>,
|
||||
|
@ -60,6 +60,8 @@ fn declaration<V: ASTVisitor>(v: &mut V, decl: &Declaration) {
|
||||
v.implemention(type_name, interface_name.as_ref(), block);
|
||||
}
|
||||
Interface { name, signatures } => v.interface(name, signatures),
|
||||
//TODO fill this in
|
||||
Annotation { .. } => ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,6 +371,7 @@ 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(|decl| { StatementKind::Declaration(decl) }),
|
||||
Keyword(Func)=> self.func_declaration().map(|func| { StatementKind::Declaration(func) }),
|
||||
Keyword(Let) => self.binding_declaration().map(StatementKind::Declaration),
|
||||
@ -384,6 +385,23 @@ impl Parser {
|
||||
Ok(Statement { kind, id, location: tok.location })
|
||||
}
|
||||
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn annotation(&mut self) -> ParseResult<Declaration> {
|
||||
expect!(self, AtSign);
|
||||
let name = self.identifier()?;
|
||||
let arguments = if let LParen = self.token_handler.peek().get_kind() {
|
||||
delimited!(self, LParen, expression, Comma, RParen)
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
Ok(Declaration::Annotation {
|
||||
name,
|
||||
arguments,
|
||||
})
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn type_declaration(&mut self) -> ParseResult<Declaration> {
|
||||
expect!(self, Keyword(Type));
|
||||
@ -668,6 +686,7 @@ impl Parser {
|
||||
#[recursive_descent_method]
|
||||
fn call_expr(&mut self) -> ParseResult<Expression> {
|
||||
let mut expr = self.index_expr()?;
|
||||
//TODO look at this
|
||||
while let LParen = self.token_handler.peek_kind() {
|
||||
let arguments = delimited!(self, LParen, invocation_argument, Comma, RParen);
|
||||
expr = Expression::new(self.id_store.fresh(), ExpressionKind::Call { f: Box::new(expr), arguments }); //TODO no type anno is incorrect
|
||||
|
@ -840,3 +840,47 @@ module!(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn annotations() {
|
||||
parse_test! {
|
||||
r#"
|
||||
@test_annotation
|
||||
fn some_function() {
|
||||
|
||||
}"#,
|
||||
AST {
|
||||
id: Default::default(),
|
||||
statements: vec![
|
||||
decl!(Annotation { name: rc!(test_annotation), arguments: vec![] }),
|
||||
decl!(FuncDecl(
|
||||
Signature { name: rc!(some_function), operator: false, params: vec![], type_anno: None }
|
||||
, vec![]
|
||||
)
|
||||
)
|
||||
]
|
||||
}
|
||||
};
|
||||
parse_test! {
|
||||
r#"
|
||||
@test_annotation(some, value)
|
||||
fn some_function() {
|
||||
|
||||
}"#,
|
||||
AST {
|
||||
id: Default::default(),
|
||||
statements: vec![
|
||||
decl!(Annotation { name: rc!(test_annotation), arguments: vec![
|
||||
ex!(val!("some")),
|
||||
ex!(val!("value"))
|
||||
] }),
|
||||
decl!(FuncDecl(
|
||||
Signature { name: rc!(some_function), operator: false, params: vec![], type_anno: None }
|
||||
, vec![]
|
||||
)
|
||||
)
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -327,6 +327,7 @@ impl<'a> Reducer<'a> {
|
||||
TypeAlias { .. } => Stmt::Noop,
|
||||
Interface { .. } => Stmt::Noop,
|
||||
Impl { .. } => Stmt::Expr(Expr::UnimplementedSigilValue),
|
||||
Annotation { .. } => Stmt::Noop,
|
||||
_ => Stmt::Expr(Expr::UnimplementedSigilValue),
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ pub enum TokenKind {
|
||||
LAngleBracket, RAngleBracket,
|
||||
LCurlyBrace, RCurlyBrace,
|
||||
Pipe, Backslash,
|
||||
AtSign,
|
||||
|
||||
|
||||
Comma, Period, Colon, Underscore,
|
||||
Slash, Equals,
|
||||
@ -125,7 +127,7 @@ impl Token {
|
||||
}
|
||||
}
|
||||
|
||||
const OPERATOR_CHARS: [char; 18] = ['!', '$', '%', '&', '*', '+', '-', '.', ':', '<', '>', '=', '?', '@', '^', '|', '~', '`'];
|
||||
const OPERATOR_CHARS: [char; 17] = ['!', '$', '%', '&', '*', '+', '-', '.', ':', '<', '>', '=', '?', '^', '|', '~', '`'];
|
||||
fn is_operator(c: &char) -> bool {
|
||||
OPERATOR_CHARS.iter().any(|x| x == c)
|
||||
}
|
||||
@ -183,6 +185,7 @@ pub fn tokenize(input: &str) -> Vec<Token> {
|
||||
'[' => LSquareBracket, ']' => RSquareBracket,
|
||||
'"' => handle_quote(&mut input, None),
|
||||
'\\' => Backslash,
|
||||
'@' => AtSign,
|
||||
c if c.is_digit(10) => handle_digit(c, &mut input),
|
||||
c if c.is_alphabetic() || c == '_' => handle_alphabetic(c, &mut input),
|
||||
c if is_operator(&c) => handle_operator(c, &mut input),
|
||||
|
Loading…
Reference in New Issue
Block a user