feat: Add support for function declarations.
This commit is contained in:
18
src/ast.rs
18
src/ast.rs
@@ -103,3 +103,21 @@ pub enum Type {
|
||||
|
||||
Named { name: Box<str>, name_span: Span },
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Declaration {
|
||||
Function {
|
||||
name: Box<str>,
|
||||
name_span: Span,
|
||||
parameters: Vec<Parameter>,
|
||||
return_type: Option<Type>,
|
||||
body: Option<Statement>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Parameter {
|
||||
pub name: Box<str>,
|
||||
pub name_span: Span,
|
||||
pub type_: Type,
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ pub mod parser;
|
||||
pub mod token;
|
||||
|
||||
fn main() {
|
||||
let mut parser = Parser::new("{ let return_code: i32 = 12; return return_code; }");
|
||||
let mut parser = Parser::new(include_str!("../example/simple.bky"));
|
||||
|
||||
println!("{:#?}", parser.parse_statement());
|
||||
println!("{:#?}", parser.parse_declaration());
|
||||
}
|
||||
|
||||
@@ -56,6 +56,90 @@ impl<'src> Parser<'src> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_declaration(&mut self) -> ParserResult<Declaration> {
|
||||
let peek_tok = self.peek_no_eof()?;
|
||||
|
||||
match peek_tok.kind {
|
||||
TokenKind::KwFn => self.parse_function_declaration(),
|
||||
|
||||
found => Err(ParserError::UnexpectedToken {
|
||||
expected: &[TokenKind::KwFn],
|
||||
found,
|
||||
span: peek_tok.span,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_function_declaration(&mut self) -> ParserResult<Declaration> {
|
||||
self.expect(&[TokenKind::KwFn])?;
|
||||
|
||||
let (name, name_span) = {
|
||||
let token = self.expect(&[TokenKind::Identifier])?;
|
||||
|
||||
(token.text.to_string().into_boxed_str(), token.span)
|
||||
};
|
||||
|
||||
self.expect(&[TokenKind::LeftParen])?;
|
||||
|
||||
let parameters = self.parse_function_parameters()?;
|
||||
|
||||
self.expect(&[TokenKind::RightParen])?;
|
||||
|
||||
let return_type = if self.is_peek(TokenKind::Colon) {
|
||||
self.consume();
|
||||
Some(self.parse_type()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let body = if self.is_peek(TokenKind::LeftBrace) {
|
||||
Some(self.parse_compound_statement()?)
|
||||
} else {
|
||||
self.expect(&[TokenKind::Semicolon])?;
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Declaration::Function {
|
||||
name,
|
||||
name_span,
|
||||
parameters,
|
||||
return_type,
|
||||
body,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_function_parameters(&mut self) -> ParserResult<Vec<Parameter>> {
|
||||
let mut parameters = Vec::new();
|
||||
|
||||
loop {
|
||||
if self.is_peek(TokenKind::RightParen) {
|
||||
break;
|
||||
}
|
||||
|
||||
if !parameters.is_empty() {
|
||||
self.expect(&[TokenKind::Comma])?;
|
||||
}
|
||||
|
||||
let (name, name_span) = {
|
||||
let token = self.expect(&[TokenKind::Identifier])?;
|
||||
|
||||
(token.text.to_string().into_boxed_str(), token.span)
|
||||
};
|
||||
|
||||
self.expect(&[TokenKind::Colon])?;
|
||||
|
||||
let type_ = self.parse_type()?;
|
||||
|
||||
parameters.push(Parameter {
|
||||
name,
|
||||
name_span,
|
||||
type_,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(parameters)
|
||||
}
|
||||
|
||||
pub fn parse_type(&mut self) -> ParserResult<Type> {
|
||||
let name_tok = self.expect(&[TokenKind::Identifier])?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user