devalang_core/core/parser/handler/identifier/
function.rs

1use 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(); // consume 'fn'
14
15    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(); // consume function name
39
40    let mut parameters = Vec::new();
41
42    // Expect '('
43    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(); // consume '('
50
51    // Parse parameters until ')'
52    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(); // consume ')'
61    } else {
62        return crate::core::parser::statement::error_from_token(
63            name_token.clone(),
64            "Expected ')' after parameters".to_string(),
65        );
66    }
67
68    // Expect colon
69    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(); // consume ':'
76
77    // Collect ALL tokens indented after this line until Dedent
78    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    // Parse those tokens into block statements
93    let body = parser.parse_block(body_tokens.clone(), global_store);
94
95    // Skip Dedent if present
96    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}