refactor: impl parseable for function declaration

master
Araozu 2024-06-04 18:46:00 -05:00
parent 778a1390a0
commit 8d5fcd1ce3
7 changed files with 183 additions and 179 deletions

View File

@ -11,6 +11,7 @@ mod unary;
/// Expression is defined in the grammar. /// Expression is defined in the grammar.
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> { pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
// TODO: This must be newline/indentation aware
equality::try_parse(tokens, pos) equality::try_parse(tokens, pos)
} }

View File

@ -1,4 +1,2 @@
pub mod arguments_list; pub mod arguments_list;
pub mod function_declaration;
pub mod params_list; pub mod params_list;

View File

@ -35,8 +35,7 @@ impl<'a> Parseable<'a> for VariableBinding<'a> {
/* /*
* datatype * datatype
*/ */
let (datatype, next_pos) = match parse_token_type(tokens, next_pos, TokenType::Datatype) let (datatype, next_pos) = match parse_token_type(tokens, next_pos, TokenType::Datatype) {
{
Ok((t, next)) => (Some(t), next), Ok((t, next)) => (Some(t), next),
_ => (None, next_pos), _ => (None, next_pos),
}; };
@ -50,45 +49,45 @@ impl<'a> Parseable<'a> for VariableBinding<'a> {
/* /*
* identifier * identifier
*/ */
let (identifier, next_pos) = let (identifier, next_pos) = match parse_token_type(tokens, next_pos, TokenType::Identifier)
match parse_token_type(tokens, next_pos, TokenType::Identifier) { {
Ok((t, n)) => (t, n), Ok((t, n)) => (t, n),
Err(ParsingError::Mismatch(token)) => { Err(ParsingError::Mismatch(token)) => {
// The parser found a token, but it's not an identifier // The parser found a token, but it's not an identifier
return Err(ParsingError::Err(SyntaxError { return Err(ParsingError::Err(SyntaxError {
error_start: token.position, error_start: token.position,
error_end: token.get_end_position(), error_end: token.get_end_position(),
reason: "There should be an identifier after a binding".into(), reason: "There should be an identifier after a binding".into(),
})); }));
} }
_ => { _ => {
// The parser didn't find an Identifier after VAL/VAR or the Datatype // The parser didn't find an Identifier after VAL/VAR or the Datatype
match (binding_token, datatype) { match (binding_token, datatype) {
(Some(binding_token), None) => { (Some(binding_token), None) => {
return Err(ParsingError::Err(SyntaxError { return Err(ParsingError::Err(SyntaxError {
reason: format!( reason: format!(
"There should be an identifier after a `{}` token", "There should be an identifier after a `{}` token",
if is_var { "var" } else { "val" } if is_var { "var" } else { "val" }
), ),
error_start: binding_token.position, error_start: binding_token.position,
error_end: binding_token.get_end_position(), error_end: binding_token.get_end_position(),
})); }));
} }
(_, Some(datatype_token)) => { (_, Some(datatype_token)) => {
return Err(ParsingError::Err(SyntaxError { return Err(ParsingError::Err(SyntaxError {
reason: "There should be an identifier after the datatype".into(), reason: "There should be an identifier after the datatype".into(),
error_start: datatype_token.position, error_start: datatype_token.position,
error_end: datatype_token.get_end_position(), error_end: datatype_token.get_end_position(),
})); }));
} }
_ => { _ => {
unreachable!( unreachable!(
"Illegal parser state: binding_token and datatype are both None" "Illegal parser state: binding_token and datatype are both None"
) )
} }
}; };
} }
}; };
/* /*
* Equal (=) operator * Equal (=) operator

View File

@ -1,7 +1,9 @@
use crate::{ use crate::{
lexic::token::Token, lexic::token::Token,
syntax::{ syntax::{
ast::Expression, expression, parseable::{Parseable, ParsingResult} ast::Expression,
expression,
parseable::{Parseable, ParsingResult},
}, },
}; };

View File

@ -1,134 +1,139 @@
use crate::{ use crate::{
error_handling::SyntaxError, error_handling::SyntaxError,
lexic::token::{Token, TokenType}, lexic::token::{Token, TokenType},
syntax::{utils::try_operator, ParsingError, ParsingResult}, syntax::{
ast::FunctionDeclaration,
block::parse_block,
functions::params_list::parse_params_list,
parseable::{Parseable, ParsingError, ParsingResult},
utils::{parse_token_type, try_operator},
},
}; };
use super::{ impl<'a> Parseable<'a> for FunctionDeclaration<'a> {
super::{ast::FunctionDeclaration, block::parse_block, utils::parse_token_type}, type Item = FunctionDeclaration<'a>;
params_list::parse_params_list,
};
/* fn try_parse(tokens: &'a Vec<Token>, current_pos: usize) -> ParsingResult<'a, Self::Item> {
function declaration = "fun", identifier, params list, return type?, block; let mut current_pos = current_pos;
return type = "->", datatype; // `fun` keyword
*/ let (fun_keyword, next_pos) = match parse_token_type(tokens, current_pos, TokenType::FUN) {
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<FunctionDeclaration> { Ok((t, next)) => (t, next),
let mut current_pos = pos; _ => return Err(ParsingError::Unmatched),
// `fun` keyword
let (fun_keyword, next_pos) = match parse_token_type(tokens, current_pos, TokenType::FUN) {
Ok((t, next)) => (t, next),
_ => return Err(ParsingError::Unmatched),
};
current_pos = next_pos;
// identifier
let (identifier, next_pos) = match parse_token_type(tokens, current_pos, TokenType::Identifier)
{
Ok((id, next)) => (id, next),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
Err(ParsingError::Mismatch(wrong_token)) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected an identifier after the `fun` keyword."),
error_start: wrong_token.position,
error_end: wrong_token.get_end_position(),
}));
}
Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected an identifier after the `fun` keyword."),
error_start: fun_keyword.position,
error_end: fun_keyword.get_end_position(),
}));
}
};
current_pos = next_pos;
// Params list
let (params_list, next_pos) = match parse_params_list(tokens, current_pos) {
Ok((params, next_pos)) => (params, next_pos),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
Err(ParsingError::Mismatch(wrong_token)) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected an opening paren after the function identifier."),
error_start: wrong_token.position,
error_end: wrong_token.get_end_position(),
}));
}
Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected an opening paren after the function identifier."),
error_start: identifier.position,
error_end: identifier.get_end_position(),
}));
}
};
current_pos = next_pos;
// Try to parse a return type
let (return_type, next_pos) = 'return_label: {
let (arrow_op, next_pos) = match try_operator(tokens, current_pos, "->".into()) {
Ok((op, next)) => (op, next),
_ => break 'return_label (None, current_pos),
}; };
current_pos = next_pos;
// At this point the '->' operator was matched, so we expect a datatype // identifier
match parse_token_type(tokens, next_pos, TokenType::Datatype) { let (identifier, next_pos) =
Ok((t, next)) => (Some(t), next), match parse_token_type(tokens, current_pos, TokenType::Identifier) {
Ok((id, next)) => (id, next),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
Err(ParsingError::Mismatch(wrong_token)) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected an identifier after the `fun` keyword."),
error_start: wrong_token.position,
error_end: wrong_token.get_end_position(),
}));
}
Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected an identifier after the `fun` keyword."),
error_start: fun_keyword.position,
error_end: fun_keyword.get_end_position(),
}));
}
};
current_pos = next_pos;
// Params list
// TODO: impl Parseable
let (params_list, next_pos) = match parse_params_list(tokens, current_pos) {
Ok((params, next_pos)) => (params, next_pos),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
Err(ParsingError::Mismatch(wrong_token)) => { Err(ParsingError::Mismatch(wrong_token)) => {
return Err(ParsingError::Err(SyntaxError { return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a datatype after the arrow operator."), reason: String::from(
"Expected an opening paren after the function identifier.",
),
error_start: wrong_token.position, error_start: wrong_token.position,
error_end: wrong_token.get_end_position(), error_end: wrong_token.get_end_position(),
})); }));
} }
Err(ParsingError::Unmatched) => { Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError { return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a datatype after the arrow operator."), reason: String::from(
error_start: arrow_op.position, "Expected an opening paren after the function identifier.",
error_end: arrow_op.get_end_position(), ),
error_start: identifier.position,
error_end: identifier.get_end_position(),
})); }));
} }
} };
}; current_pos = next_pos;
current_pos = next_pos;
// Function body (block) // Try to parse a return type
let (block, next_pos) = match parse_block(tokens, current_pos) { let (return_type, next_pos) = 'return_label: {
Ok((block, next_pos)) => (block, next_pos), let (arrow_op, next_pos) = match try_operator(tokens, current_pos, "->".into()) {
Err(ParsingError::Err(error)) => { Ok((op, next)) => (op, next),
return Err(ParsingError::Err(error)); _ => break 'return_label (None, current_pos),
} };
Err(ParsingError::Mismatch(wrong_token)) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a block after the function declaration."),
error_start: wrong_token.position,
error_end: wrong_token.get_end_position(),
}));
}
Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a block after the function declaration."),
error_start: identifier.position,
error_end: identifier.get_end_position(),
}));
}
};
current_pos = next_pos;
// Construct and return the function declaration // At this point the '->' operator was matched, so we expect a datatype
Ok(( match parse_token_type(tokens, next_pos, TokenType::Datatype) {
FunctionDeclaration { Ok((t, next)) => (Some(t), next),
identifier: &identifier, Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
return_type, Err(ParsingError::Mismatch(wrong_token)) => {
params_list: Box::new(params_list), return Err(ParsingError::Err(SyntaxError {
block: Box::new(block), reason: String::from("Expected a datatype after the arrow operator."),
}, error_start: wrong_token.position,
current_pos, error_end: wrong_token.get_end_position(),
)) }));
}
Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a datatype after the arrow operator."),
error_start: arrow_op.position,
error_end: arrow_op.get_end_position(),
}));
}
}
};
current_pos = next_pos;
// Function body (block)
let (block, next_pos) = match parse_block(tokens, current_pos) {
Ok((block, next_pos)) => (block, next_pos),
Err(ParsingError::Err(error)) => {
return Err(ParsingError::Err(error));
}
Err(ParsingError::Mismatch(wrong_token)) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a block after the function declaration."),
error_start: wrong_token.position,
error_end: wrong_token.get_end_position(),
}));
}
Err(ParsingError::Unmatched) => {
return Err(ParsingError::Err(SyntaxError {
reason: String::from("Expected a block after the function declaration."),
error_start: identifier.position,
error_end: identifier.get_end_position(),
}));
}
};
current_pos = next_pos;
// Construct and return the function declaration
Ok((
FunctionDeclaration {
identifier: &identifier,
return_type,
params_list: Box::new(params_list),
block: Box::new(block),
},
current_pos,
))
}
} }
#[cfg(test)] #[cfg(test)]
@ -140,7 +145,7 @@ mod tests {
#[test] #[test]
fn should_return_none_on_wrong_initial_token() { fn should_return_none_on_wrong_initial_token() {
let tokens = get_tokens(&String::from("val identifier = 20")).unwrap(); let tokens = get_tokens(&String::from("val identifier = 20")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
let Err(ParsingError::Unmatched) = fun_decl else { let Err(ParsingError::Unmatched) = fun_decl else {
panic!("Expected an unmatched result: {:?}", fun_decl); panic!("Expected an unmatched result: {:?}", fun_decl);
@ -150,7 +155,7 @@ mod tests {
#[test] #[test]
fn should_not_parse_fun_without_identifier() { fn should_not_parse_fun_without_identifier() {
let tokens = get_tokens(&String::from("fun = 20")).unwrap(); let tokens = get_tokens(&String::from("fun = 20")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -165,7 +170,7 @@ mod tests {
} }
let tokens = get_tokens(&String::from("fun")).unwrap(); let tokens = get_tokens(&String::from("fun")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
assert_eq!( assert_eq!(
@ -182,7 +187,7 @@ mod tests {
#[test] #[test]
fn should_not_parse_fun_without_parens() { fn should_not_parse_fun_without_parens() {
let tokens = get_tokens(&String::from("fun id =")).unwrap(); let tokens = get_tokens(&String::from("fun id =")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -197,7 +202,7 @@ mod tests {
} }
let tokens = get_tokens(&String::from("fun id")).unwrap(); let tokens = get_tokens(&String::from("fun id")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
assert_eq!( assert_eq!(
@ -214,7 +219,7 @@ mod tests {
#[test] #[test]
fn should_not_parse_fun_without_closing_paren() { fn should_not_parse_fun_without_closing_paren() {
let tokens = get_tokens(&String::from("fun id(=")).unwrap(); let tokens = get_tokens(&String::from("fun id(=")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -229,7 +234,7 @@ mod tests {
} }
let tokens = get_tokens(&String::from("fun id(")).unwrap(); let tokens = get_tokens(&String::from("fun id(")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
assert_eq!( assert_eq!(
@ -246,7 +251,7 @@ mod tests {
#[test] #[test]
fn should_not_parse_fun_when_missing_id() { fn should_not_parse_fun_when_missing_id() {
let tokens = get_tokens(&String::from("fun")).unwrap(); let tokens = get_tokens(&String::from("fun")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -262,7 +267,7 @@ mod tests {
let tokens = get_tokens(&String::from("fun\n")).unwrap(); let tokens = get_tokens(&String::from("fun\n")).unwrap();
println!("{:?}", tokens); println!("{:?}", tokens);
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -280,7 +285,7 @@ mod tests {
#[test] #[test]
fn should_not_parse_fun_without_opening_brace() { fn should_not_parse_fun_without_opening_brace() {
let tokens = get_tokens(&String::from("fun id() =")).unwrap(); let tokens = get_tokens(&String::from("fun id() =")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -295,7 +300,7 @@ mod tests {
} }
let tokens = get_tokens(&String::from("fun id()")).unwrap(); let tokens = get_tokens(&String::from("fun id()")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
assert_eq!( assert_eq!(
@ -312,7 +317,7 @@ mod tests {
#[test] #[test]
fn should_not_parse_fun_without_closing_brace() { fn should_not_parse_fun_without_closing_brace() {
let tokens = get_tokens(&String::from("fun id() { 20")).unwrap(); let tokens = get_tokens(&String::from("fun id() { 20")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -324,7 +329,7 @@ mod tests {
} }
let tokens = get_tokens(&String::from("fun id() {")).unwrap(); let tokens = get_tokens(&String::from("fun id() {")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -339,7 +344,7 @@ mod tests {
#[test] #[test]
fn should_parse_simple_function_declaration() { fn should_parse_simple_function_declaration() {
let tokens = get_tokens(&String::from("fun id() {}")).unwrap(); let tokens = get_tokens(&String::from("fun id() {}")).unwrap();
let (function_declaration, _) = try_parse(&tokens, 0).unwrap(); let (function_declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(function_declaration.identifier.value, String::from("id")); assert_eq!(function_declaration.identifier.value, String::from("id"));
assert_eq!(function_declaration.return_type, None); assert_eq!(function_declaration.return_type, None);
@ -348,7 +353,7 @@ mod tests {
#[test] #[test]
fn should_parse_return_type() { fn should_parse_return_type() {
let tokens = get_tokens(&String::from("fun id() -> String {}")).unwrap(); let tokens = get_tokens(&String::from("fun id() -> String {}")).unwrap();
let (function_declaration, _) = try_parse(&tokens, 0).unwrap(); let (function_declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(function_declaration.identifier.value, String::from("id")); assert_eq!(function_declaration.identifier.value, String::from("id"));
assert_eq!( assert_eq!(
@ -360,7 +365,7 @@ mod tests {
#[test] #[test]
fn should_throw_error_on_return_type_1() { fn should_throw_error_on_return_type_1() {
let tokens = get_tokens(&String::from("fun id() -> {}")).unwrap(); let tokens = get_tokens(&String::from("fun id() -> {}")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -375,7 +380,7 @@ mod tests {
#[test] #[test]
fn should_throw_error_on_return_type_2() { fn should_throw_error_on_return_type_2() {
let tokens = get_tokens(&String::from("fun id() -> ")).unwrap(); let tokens = get_tokens(&String::from("fun id() -> ")).unwrap();
let fun_decl = try_parse(&tokens, 0); let fun_decl = FunctionDeclaration::try_parse(&tokens, 0);
match fun_decl { match fun_decl {
Err(ParsingError::Err(err)) => { Err(ParsingError::Err(err)) => {
@ -397,7 +402,7 @@ mod whitespace_test {
#[test] #[test]
fn should_ignore_whitespace_1() { fn should_ignore_whitespace_1() {
let tokens = get_tokens(&String::from("fun\nid() {}")).unwrap(); let tokens = get_tokens(&String::from("fun\nid() {}")).unwrap();
let (declaration, _) = try_parse(&tokens, 0).unwrap(); let (declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(declaration.identifier.value, (String::from("id"))); assert_eq!(declaration.identifier.value, (String::from("id")));
} }
@ -405,7 +410,7 @@ mod whitespace_test {
#[test] #[test]
fn should_ignore_whitespace_2() { fn should_ignore_whitespace_2() {
let tokens = get_tokens(&String::from("fun\nid\n() {}")).unwrap(); let tokens = get_tokens(&String::from("fun\nid\n() {}")).unwrap();
let (declaration, _) = try_parse(&tokens, 0).unwrap(); let (declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(declaration.identifier.value, (String::from("id"))); assert_eq!(declaration.identifier.value, (String::from("id")));
} }
@ -413,7 +418,7 @@ mod whitespace_test {
#[test] #[test]
fn should_ignore_whitespace_3() { fn should_ignore_whitespace_3() {
let tokens = get_tokens(&String::from("fun\nid\n(\n) {}")).unwrap(); let tokens = get_tokens(&String::from("fun\nid\n(\n) {}")).unwrap();
let (declaration, _) = try_parse(&tokens, 0).unwrap(); let (declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(declaration.identifier.value, (String::from("id"))); assert_eq!(declaration.identifier.value, (String::from("id")));
} }
@ -421,14 +426,14 @@ mod whitespace_test {
#[test] #[test]
fn should_ignore_whitespace_4() { fn should_ignore_whitespace_4() {
let tokens = get_tokens(&String::from("fun id\n(\n)\n{}")).unwrap(); let tokens = get_tokens(&String::from("fun id\n(\n)\n{}")).unwrap();
let (declaration, _) = try_parse(&tokens, 0).unwrap(); let (declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(declaration.identifier.value, (String::from("id"))); assert_eq!(declaration.identifier.value, (String::from("id")));
} }
#[test] #[test]
fn should_ignore_whitespace_5() { fn should_ignore_whitespace_5() {
let tokens = get_tokens(&String::from("fun\nid() \n{\n}")).unwrap(); let tokens = get_tokens(&String::from("fun\nid() \n{\n}")).unwrap();
let (declaration, _) = try_parse(&tokens, 0).unwrap(); let (declaration, _) = FunctionDeclaration::try_parse(&tokens, 0).unwrap();
assert_eq!(declaration.identifier.value, (String::from("id"))); assert_eq!(declaration.identifier.value, (String::from("id")));
} }
} }

View File

@ -1,4 +1,5 @@
pub mod binding; pub mod binding;
pub mod expression; pub mod expression;
pub mod function_declaration;
pub mod module; pub mod module;
pub mod statement; pub mod statement;

View File

@ -1,6 +1,5 @@
use crate::syntax::{ use crate::syntax::{
ast::{var_binding::VariableBinding, Statement}, ast::{var_binding::VariableBinding, FunctionDeclaration, Statement},
functions::function_declaration,
parseable::{Parseable, ParsingError}, parseable::{Parseable, ParsingError},
}; };
@ -24,8 +23,7 @@ impl<'a> Parseable<'a> for Statement<'a> {
} }
// Try to parse a function declaration // Try to parse a function declaration
// TODO: Rewrite function_declaration to use Parseable match FunctionDeclaration::try_parse(tokens, current_pos) {
match function_declaration::try_parse(tokens, current_pos) {
Ok((prod, next)) => { Ok((prod, next)) => {
return Ok((Statement::FnDecl(prod), next)); return Ok((Statement::FnDecl(prod), next));
} }