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

1use crate::core::{
2    lexer::token::TokenKind,
3    parser::{
4        driver::Parser,
5        statement::{Statement, StatementKind},
6    },
7    shared::value::Value,
8    store::global::GlobalStore,
9};
10
11pub fn parse_function_token(parser: &mut Parser, global_store: &mut GlobalStore) -> Statement {
12    parser.advance(); // consume 'fn'
13
14    let fn_token = match parser.previous_clone() {
15        Some(tok) => tok,
16        None => return Statement::unknown(),
17    };
18
19    let name_token = match parser.peek_clone() {
20        Some(tok) => tok,
21        None => return Statement::error(fn_token, "Expected function name after 'fn'".to_string()),
22    };
23
24    if name_token.kind != TokenKind::Identifier {
25        return Statement::error(
26            name_token.clone(),
27            "Expected function name to be an identifier".to_string(),
28        );
29    }
30
31    let function_name = name_token.lexeme.clone();
32    parser.advance(); // consume function name
33
34    let mut parameters = Vec::new();
35
36    // Expect '('
37    if parser.peek_kind() != Some(TokenKind::LParen) {
38        return Statement::error(
39            name_token.clone(),
40            "Expected '(' after function name".to_string(),
41        );
42    }
43    parser.advance(); // consume '('
44
45    // Parse parameters until ')'
46    let tokens = parser.collect_until(|t| t.kind == TokenKind::RParen || t.kind == TokenKind::EOF);
47    for token in tokens {
48        if token.kind == TokenKind::Identifier {
49            parameters.push(token.lexeme.clone());
50        }
51    }
52
53    if parser.peek_kind() == Some(TokenKind::RParen) {
54        parser.advance(); // consume ')'
55    } else {
56        return Statement::error(
57            name_token.clone(),
58            "Expected ')' after parameters".to_string(),
59        );
60    }
61
62    // Expect colon
63    if parser.peek_kind() != Some(TokenKind::Colon) {
64        return Statement::error(name_token.clone(), "Expected ':' after ')'".to_string());
65    }
66    parser.advance(); // consume ':'
67
68    // Collect ALL tokens indented after this line until Dedent
69    let base_indent = fn_token.indent;
70    let mut body_tokens = Vec::new();
71
72    while let Some(tok) = parser.peek() {
73        if tok.kind == TokenKind::Dedent && tok.indent <= base_indent {
74            break;
75        }
76        body_tokens.push(parser.advance().unwrap().clone());
77    }
78
79    // Parse those tokens into block statements
80    let body = parser.parse_block(body_tokens.clone(), global_store);
81
82    // Skip Dedent if present
83    if let Some(tok) = parser.peek() {
84        if tok.kind == TokenKind::Dedent {
85            parser.advance();
86        }
87    }
88
89    Statement {
90        kind: StatementKind::Function {
91            name: function_name.clone(),
92            parameters: parameters.clone(),
93            body: body.clone(),
94        },
95        value: Value::Null,
96        indent: fn_token.indent,
97        line: fn_token.line,
98        column: fn_token.column,
99    }
100}