Add parsing for annotations
This commit is contained in:
parent
3b5ebf92b4
commit
248af74ec0
@ -114,9 +114,28 @@ pub enum Declaration {
|
|||||||
Interface {
|
Interface {
|
||||||
name: Rc<String>,
|
name: Rc<String>,
|
||||||
signatures: Vec<Signature>
|
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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
pub name: Rc<String>,
|
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);
|
v.implemention(type_name, interface_name.as_ref(), block);
|
||||||
}
|
}
|
||||||
Interface { name, signatures } => v.interface(name, signatures),
|
Interface { name, signatures } => v.interface(name, signatures),
|
||||||
|
//TODO fill this in
|
||||||
|
Annotation { .. } => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +371,7 @@ 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),
|
||||||
Keyword(Type) => self.type_declaration().map(|decl| { StatementKind::Declaration(decl) }),
|
Keyword(Type) => self.type_declaration().map(|decl| { StatementKind::Declaration(decl) }),
|
||||||
Keyword(Func)=> self.func_declaration().map(|func| { StatementKind::Declaration(func) }),
|
Keyword(Func)=> self.func_declaration().map(|func| { StatementKind::Declaration(func) }),
|
||||||
Keyword(Let) => self.binding_declaration().map(StatementKind::Declaration),
|
Keyword(Let) => self.binding_declaration().map(StatementKind::Declaration),
|
||||||
@ -384,6 +385,23 @@ impl Parser {
|
|||||||
Ok(Statement { kind, id, location: tok.location })
|
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]
|
#[recursive_descent_method]
|
||||||
fn type_declaration(&mut self) -> ParseResult<Declaration> {
|
fn type_declaration(&mut self) -> ParseResult<Declaration> {
|
||||||
expect!(self, Keyword(Type));
|
expect!(self, Keyword(Type));
|
||||||
@ -668,6 +686,7 @@ impl Parser {
|
|||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn call_expr(&mut self) -> ParseResult<Expression> {
|
fn call_expr(&mut self) -> ParseResult<Expression> {
|
||||||
let mut expr = self.index_expr()?;
|
let mut expr = self.index_expr()?;
|
||||||
|
//TODO look at this
|
||||||
while let LParen = self.token_handler.peek_kind() {
|
while let LParen = self.token_handler.peek_kind() {
|
||||||
let arguments = delimited!(self, LParen, invocation_argument, Comma, RParen);
|
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
|
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,
|
TypeAlias { .. } => Stmt::Noop,
|
||||||
Interface { .. } => Stmt::Noop,
|
Interface { .. } => Stmt::Noop,
|
||||||
Impl { .. } => Stmt::Expr(Expr::UnimplementedSigilValue),
|
Impl { .. } => Stmt::Expr(Expr::UnimplementedSigilValue),
|
||||||
|
Annotation { .. } => Stmt::Noop,
|
||||||
_ => Stmt::Expr(Expr::UnimplementedSigilValue),
|
_ => Stmt::Expr(Expr::UnimplementedSigilValue),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ pub enum TokenKind {
|
|||||||
LAngleBracket, RAngleBracket,
|
LAngleBracket, RAngleBracket,
|
||||||
LCurlyBrace, RCurlyBrace,
|
LCurlyBrace, RCurlyBrace,
|
||||||
Pipe, Backslash,
|
Pipe, Backslash,
|
||||||
|
AtSign,
|
||||||
|
|
||||||
|
|
||||||
Comma, Period, Colon, Underscore,
|
Comma, Period, Colon, Underscore,
|
||||||
Slash, Equals,
|
Slash, Equals,
|
||||||
@ -125,7 +127,7 @@ impl Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const OPERATOR_CHARS: [char; 18] = ['!', '$', '%', '&', '*', '+', '-', '.', ':', '<', '>', '=', '?', '@', '^', '|', '~', '`'];
|
const OPERATOR_CHARS: [char; 17] = ['!', '$', '%', '&', '*', '+', '-', '.', ':', '<', '>', '=', '?', '^', '|', '~', '`'];
|
||||||
fn is_operator(c: &char) -> bool {
|
fn is_operator(c: &char) -> bool {
|
||||||
OPERATOR_CHARS.iter().any(|x| x == c)
|
OPERATOR_CHARS.iter().any(|x| x == c)
|
||||||
}
|
}
|
||||||
@ -183,6 +185,7 @@ pub fn tokenize(input: &str) -> Vec<Token> {
|
|||||||
'[' => LSquareBracket, ']' => RSquareBracket,
|
'[' => LSquareBracket, ']' => RSquareBracket,
|
||||||
'"' => handle_quote(&mut input, None),
|
'"' => handle_quote(&mut input, None),
|
||||||
'\\' => Backslash,
|
'\\' => Backslash,
|
||||||
|
'@' => AtSign,
|
||||||
c if c.is_digit(10) => handle_digit(c, &mut input),
|
c if c.is_digit(10) => handle_digit(c, &mut input),
|
||||||
c if c.is_alphabetic() || c == '_' => handle_alphabetic(c, &mut input),
|
c if c.is_alphabetic() || c == '_' => handle_alphabetic(c, &mut input),
|
||||||
c if is_operator(&c) => handle_operator(c, &mut input),
|
c if is_operator(&c) => handle_operator(c, &mut input),
|
||||||
|
Loading…
Reference in New Issue
Block a user