devalang_core/core/parser/handler/identifier/
emit.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
11// Syntax:
12// emit <event> [<payload>]
13pub fn parse_emit_token(
14    parser: &mut Parser,
15    current: crate::core::lexer::token::Token,
16    _global_store: &mut GlobalStore,
17) -> Statement {
18    parser.advance(); // consume 'emit'
19
20    let Some(ev) = parser.peek_clone() else {
21        return Statement::error(current, "Expected event name after 'emit'".into());
22    };
23    if ev.kind != TokenKind::Identifier {
24        return Statement::error(ev.clone(), "Expected identifier as event name".into());
25    }
26    let event_name = ev.lexeme.clone();
27    parser.advance(); // consume event name
28
29    // Optional payload on same line: number|string|identifier|map|array
30    let mut payload: Option<Value> = None;
31    if let Some(tok) = parser.peek_clone() {
32        if tok.line == ev.line {
33            let val = match tok.kind {
34                TokenKind::String => {
35                    parser.advance();
36                    Value::String(tok.lexeme.clone())
37                }
38                TokenKind::Number => {
39                    parser.advance();
40                    Value::Number(tok.lexeme.parse().unwrap_or(0.0))
41                }
42                TokenKind::Identifier => {
43                    parser.advance();
44                    Value::Identifier(tok.lexeme.clone())
45                }
46                TokenKind::LBrace => parser.parse_map_value().unwrap_or(Value::Null),
47                TokenKind::LBracket => parser.parse_array_value().unwrap_or(Value::Null),
48                _ => Value::Null,
49            };
50            if val != Value::Null {
51                payload = Some(val);
52            }
53        }
54    }
55
56    Statement {
57        kind: StatementKind::Emit {
58            event: event_name,
59            payload: payload.clone(),
60        },
61        value: payload.unwrap_or(Value::Null),
62        indent: current.indent,
63        line: current.line,
64        column: current.column,
65    }
66}