devalang_core/core/parser/handler/
condition.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};
10use std::collections::HashMap;
11
12pub fn parse_condition_token(parser: &mut Parser, global_store: &mut GlobalStore) -> Statement {
13 parser.advance(); let Some(if_token) = parser.previous_clone() else {
15 return Statement::unknown();
16 };
17
18 let Some(condition) = parser.parse_condition_until_colon() else {
19 return Statement::error(if_token, "Expected condition after 'if'".to_string());
20 };
21
22 parser.advance_if(TokenKind::Colon);
23 let base_indent = if_token.indent;
24
25 let if_body = parser.parse_block_until_else_or_dedent(base_indent, global_store);
26
27 let mut root_map = HashMap::new();
28 root_map.insert("condition".to_string(), condition);
29 root_map.insert("body".to_string(), Value::Block(if_body));
30
31 let mut current = &mut root_map;
32
33 while let Some(tok) = parser.peek_clone() {
35 if tok.lexeme != "else" || tok.indent != base_indent {
37 break;
38 }
39
40 parser.advance(); let next_condition = if parser.peek_is("if") {
44 parser.advance(); let Some(cond) = parser.parse_condition_until_colon() else {
46 return Statement::error(
47 tok.clone(),
48 "Expected condition after 'else if'".to_string(),
49 );
50 };
51 parser.advance_if(TokenKind::Colon);
52 Some(cond)
53 } else {
54 parser.advance_if(TokenKind::Colon);
55 None
56 };
57
58 let body = parser.parse_block_until_else_or_dedent(base_indent, global_store);
59
60 let mut next_map = HashMap::new();
61 if let Some(cond) = next_condition {
62 next_map.insert("condition".to_string(), cond);
63 }
64 next_map.insert("body".to_string(), Value::Block(body));
65
66 current.insert("next".to_string(), Value::Map(next_map));
67 current = match current.get_mut("next") {
68 Some(Value::Map(map)) => map,
69 _ => break,
70 };
71 }
72
73 Statement {
74 kind: StatementKind::If,
75 value: Value::Map(root_map),
76 indent: if_token.indent,
77 line: if_token.line,
78 column: if_token.column,
79 }
80}