feat: Add support for function declarations.
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,8 +1 @@
|
|||||||
/target
|
/target
|
||||||
|
|
||||||
|
|
||||||
# Added by cargo
|
|
||||||
#
|
|
||||||
# already existing elements were commented out
|
|
||||||
|
|
||||||
#/target
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
fn main(): i32 {
|
fn add(a: i32, b: i32): i32 {
|
||||||
let return_code: i32 = 12;
|
return a + b;
|
||||||
return return_code;
|
|
||||||
}
|
}
|
||||||
18
src/ast.rs
18
src/ast.rs
@@ -103,3 +103,21 @@ pub enum Type {
|
|||||||
|
|
||||||
Named { name: Box<str>, name_span: Span },
|
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;
|
pub mod token;
|
||||||
|
|
||||||
fn main() {
|
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> {
|
pub fn parse_type(&mut self) -> ParserResult<Type> {
|
||||||
let name_tok = self.expect(&[TokenKind::Identifier])?;
|
let name_tok = self.expect(&[TokenKind::Identifier])?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user