diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 395da7d..b60f1d4 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -302,6 +302,7 @@ impl Ast { #[derive(Debug)] struct FunctionDecl { + attrs: Option, name: String, visibility: Visibility, return_type: Type, @@ -338,7 +339,7 @@ pomelo! { %extra_argument Ast; %parser pub struct Parser<'a>{}; %token #[derive(Debug)] pub enum Token<'a> {}; - // %default_type &'a str; + %type Ident &'a str; %type DocComment &'a str; %type Comment &'a str; @@ -363,6 +364,12 @@ pomelo! { list }; + %type attrs Index; + attrs ::= DocComment(text) { + let idx = extra.push(AstNode::Doc { text: text.to_string() }); + extra.push(AstNode::Attributes { attrs: vec![idx] }) + }; + typ ::= Bool { internment::Intern::new(InnerType::Bool) }; typ ::= I1 { internment::Intern::new(InnerType::Int { signed: true, size: IntSize::Bits(1) }) }; typ ::= I8 { internment::Intern::new(InnerType::Int { signed: true, size: IntSize::Bits(8) }) }; @@ -427,10 +434,12 @@ pomelo! { pl }; + decl ::= Comment(text) { extra.push(AstNode::Comment { text: text.to_string() }) }; decl ::= fn_decl(f) { extra.push(AstNode::FunctionDecl(f)) }; - fn_decl ::= vis?(visibility) Fn Ident(name) LParen parameter_list?(parameters) RParen return_type(rtype) block(body) { + fn_decl ::= attrs?(attrs) vis?(visibility) Fn Ident(name) LParen parameter_list?(parameters) RParen return_type(rtype) block(body) { let name = name.to_string(); FunctionDecl { + attrs, name, visibility: visibility.unwrap_or_default(), return_type: rtype, @@ -555,7 +564,11 @@ mod tests { #[test] fn parse() { use crate::parser::{Parser, Token}; - let input = "fn main(a: u32, b: u32) -> u32 {}"; + let input = r#" +// A simple test case +/// A function that takes two u32 parameters and returns a u32 +fn main(a: u32, b: u32) -> u32 {} +"#; let mut lex = lexer::TokenIterator::new(input); let mut mapped = lex.inspect(|t| eprintln!("{t:?}")).map(Token::from); let mut ast = crate::Ast::new();