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

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