devalang_core/core/parser/handler/identifier/
function.rs1use devalang_types::Value;
2
3use crate::core::{
4 lexer::token::TokenKind,
5 parser::{
6 driver::parser::Parser,
7 statement::{Statement, StatementKind},
8 },
9 store::global::GlobalStore,
10};
11
12pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore) -> Statement {
13 parser.advance(); let fn_token = match parser.previous_clone() {
16 Some(tok) => tok,
17 None => return Statement::unknown(),
18 };
19
20 let name_token = match parser.peek_clone() {
21 Some(tok) => tok,
22 None => {
23 return crate::core::parser::statement::error_from_token(
24 fn_token,
25 "Expected function name after 'fn'".to_string(),
26 );
27 }
28 };
29
30 if name_token.kind != TokenKind::Identifier {
31 return crate::core::parser::statement::error_from_token(
32 name_token.clone(),
33 "Expected function name to be an identifier".to_string(),
34 );
35 }
36
37 let function_name = name_token.lexeme.clone();
38 parser.advance(); let mut parameters = Vec::new();
41
42 if parser.peek_kind() != Some(TokenKind::LParen) {
44 return crate::core::parser::statement::error_from_token(
45 name_token.clone(),
46 "Expected '(' after function name".to_string(),
47 );
48 }
49 parser.advance(); let tokens = parser.collect_until(|t| t.kind == TokenKind::RParen || t.kind == TokenKind::EOF);
53 for token in tokens {
54 if token.kind == TokenKind::Identifier {
55 parameters.push(token.lexeme.clone());
56 }
57 }
58
59 if parser.peek_kind() == Some(TokenKind::RParen) {
60 parser.advance(); } else {
62 return crate::core::parser::statement::error_from_token(
63 name_token.clone(),
64 "Expected ')' after parameters".to_string(),
65 );
66 }
67
68 if parser.peek_kind() != Some(TokenKind::Colon) {
70 return crate::core::parser::statement::error_from_token(
71 name_token.clone(),
72 "Expected ':' after ')'".to_string(),
73 );
74 }
75 parser.advance(); let base_indent = fn_token.indent;
79 let mut body_tokens = Vec::new();
80
81 while let Some(tok) = parser.peek() {
82 if tok.kind == TokenKind::Dedent && tok.indent <= base_indent {
83 break;
84 }
85 if let Some(t) = parser.advance() {
86 body_tokens.push(t.clone());
87 } else {
88 break;
89 }
90 }
91
92 let body = parser.parse_block(body_tokens.clone(), global_store);
94
95 if let Some(tok) = parser.peek() {
97 if tok.kind == TokenKind::Dedent {
98 parser.advance();
99 }
100 }
101
102 Statement {
103 kind: StatementKind::Function {
104 name: function_name.clone(),
105 parameters: parameters.clone(),
106 body: body.clone(),
107 },
108 value: Value::Null,
109 indent: fn_token.indent,
110 line: fn_token.line,
111 column: fn_token.column,
112 }
113}