devalang_core/core/parser/handler/identifier/
on.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_on_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
13 let on_tok = match parser.peek_clone() {
15 Some(tok) => tok,
16 None => return Statement::unknown(),
17 };
18 parser.advance();
19
20 let event_tok = match parser.peek_clone() {
22 Some(tok) if tok.kind == TokenKind::Identifier => tok,
23 Some(other) => {
24 return crate::core::parser::statement::error_from_token(
25 other,
26 "Expected event name after 'on'".to_string(),
27 );
28 }
29 None => {
30 return crate::core::parser::statement::error_from_token(
31 on_tok,
32 "Expected event name after 'on'".to_string(),
33 );
34 }
35 };
36 let event_name = event_tok.lexeme.clone();
37 parser.advance();
38
39 let mut args: Option<Vec<Value>> = None;
41 if parser.peek_kind() == Some(TokenKind::LParen) {
42 parser.advance(); let mut collected: Vec<Value> = Vec::new();
44 while let Some(tok) = parser.peek_clone() {
46 match tok.kind {
47 TokenKind::RParen => {
48 parser.advance();
49 break;
50 }
51 TokenKind::Number => {
52 parser.advance();
53 collected.push(Value::Number(tok.lexeme.parse().unwrap_or(0.0)));
54 }
55 TokenKind::Identifier => {
56 parser.advance();
57 collected.push(Value::Identifier(tok.lexeme));
58 }
59 TokenKind::Comma => {
60 parser.advance();
61 }
62 TokenKind::Whitespace | TokenKind::Newline => {
63 parser.advance();
64 }
65 _ => {
66 break;
67 }
68 }
69 }
70 if !collected.is_empty() {
71 args = Some(collected);
72 }
73 }
74
75 if parser.peek_kind() != Some(TokenKind::Colon) {
77 return crate::core::parser::statement::error_from_token(
78 event_tok,
79 "Expected ':' after event name".to_string(),
80 );
81 }
82 parser.advance(); let base_indent = on_tok.indent;
85 let block_tokens = parser.collect_block_tokens(base_indent);
86 let body = parser.parse_block(block_tokens, _global_store);
88
89 let stmt = Statement {
90 kind: StatementKind::On {
91 event: event_name,
92 args,
93 body,
94 },
95 value: Value::Null,
96 indent: on_tok.indent,
97 line: on_tok.line,
98 column: on_tok.column,
99 };
100
101 if let StatementKind::On { event, .. } = &stmt.kind {
103 _global_store.register_event_handler(event, stmt.clone());
104 }
105
106 stmt
107}