feat: Add support for function declarations.

This commit is contained in:
Jooris Hadeler
2026-01-16 21:17:53 +01:00
parent fbf6726a78
commit cfac708644
5 changed files with 106 additions and 12 deletions

7
.gitignore vendored
View File

@@ -1,8 +1 @@
/target
# Added by cargo
#
# already existing elements were commented out
#/target

View File

@@ -1,4 +1,3 @@
fn main(): i32 {
let return_code: i32 = 12;
return return_code;
fn add(a: i32, b: i32): i32 {
return a + b;
}

View File

@@ -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,
}

View File

@@ -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());
}

View File

@@ -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])?;