devalang_core/core/parser/handler/identifier/
function.rs1use 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(); 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(); let mut parameters = Vec::new();
35
36 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(); 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(); } else {
56 return Statement::error(
57 name_token.clone(),
58 "Expected ')' after parameters".to_string(),
59 );
60 }
61
62 if parser.peek_kind() != Some(TokenKind::Colon) {
64 return Statement::error(name_token.clone(), "Expected ':' after ')'".to_string());
65 }
66 parser.advance(); 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 let body = parser.parse_block(body_tokens.clone(), global_store);
81
82 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}