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