devalang_core/core/parser/handler/
at.rs

1use crate::core::{
2    lexer::token::TokenKind,
3    parser::{ driver::Parser, statement::{ Statement, StatementKind } },
4    shared::value::Value,
5    store::global::GlobalStore,
6};
7pub fn parse_at_token(parser: &mut Parser, _global_store: &mut GlobalStore) -> Statement {
8    parser.advance(); // consume '@'
9
10    let Some(token) = parser.peek_clone() else {
11        return Statement::unknown();
12    };
13
14    let keyword = token.lexeme.as_str();
15
16    match keyword {
17        "import" => {
18            parser.advance(); // consume 'import'
19
20            if !parser.match_token(TokenKind::LBrace) {
21                return Statement::error(token, "Expected '{{' after 'import'".to_string());
22            }
23
24            let mut names = Vec::new();
25            while let Some(token) = parser.peek() {
26                match &token.kind {
27                    TokenKind::Identifier => {
28                        names.push(token.lexeme.clone());
29                        parser.advance();
30                    }
31                    TokenKind::Comma => {
32                        parser.advance();
33                    }
34                    TokenKind::RBrace => {
35                        parser.advance();
36                        break;
37                    }
38                    _ => {
39                        let message = format!(
40                            "Unexpected token in import list: {:?}",
41                            token.kind.clone()
42                        );
43                        return Statement::error(token.clone(), message);
44                    }
45                }
46            }
47
48            let Some(from_token) = parser.peek_clone() else {
49                return Statement::error(token, "Expected 'from' after import list".to_string());
50            };
51
52            if from_token.lexeme != "from" {
53                return Statement::error(token, "Expected keyword 'from'".to_string());
54            }
55
56            parser.advance(); // consume 'from'
57
58            let Some(source_token) = parser.peek() else {
59                return Statement::error(token, "Expected string after 'from'".to_string());
60            };
61
62            if source_token.kind != TokenKind::String {
63                return Statement::error(token, "Expected string after 'from'".to_string());
64            }
65
66            let source = source_token.lexeme.clone();
67            parser.advance(); // consume string
68
69            Statement {
70                kind: StatementKind::Import { names, source },
71                value: Value::Null,
72                indent: token.indent,
73                line: token.line,
74                column: token.column,
75            }
76        }
77
78        "export" => {
79            parser.advance(); // consume 'export'
80
81            parser.advance(); // consume '{'
82
83            let names_tokens = parser.collect_until(|t| TokenKind::RBrace == t.kind);
84            let mut names: Vec<String> = Vec::new();
85
86            for token in names_tokens {
87                if token.kind == TokenKind::Identifier {
88                    names.push(token.lexeme.clone());
89                } else if token.kind == TokenKind::Comma {
90                    continue; // Ignore commas
91                } else if token.kind == TokenKind::RBrace {
92                    break; // Stop at the closing brace
93                } else {
94                    return Statement::error(token, "Unexpected token in export list".to_string());
95                }
96            }
97
98            Statement {
99                kind: StatementKind::Export {
100                    names: names.clone(),
101                    source: parser.current_module.clone(),
102                },
103                value: Value::Null,
104                indent: token.indent,
105                line: token.line,
106                column: token.column,
107            }
108        }
109
110        "load" => {
111            parser.advance(); // consume 'load'
112
113            // Exemple : @load "preset.mydeva"
114            let Some(path_token) = parser.peek() else {
115                return Statement::error(token, "Expected string after 'load'".to_string());
116            };
117
118            if path_token.kind != TokenKind::String {
119                return Statement::error(token, "Expected string after 'load'".to_string());
120            }
121
122            let path = path_token.lexeme.clone();
123
124            parser.advance(); // consume string
125            parser.advance(); // consume 'as'
126
127            let Some(as_token) = parser.peek_clone() else {
128                return Statement::error(
129                    token,
130                    "Expected 'as' after path in load statement".to_string()
131                );
132            };
133
134            if as_token.kind != TokenKind::Identifier {
135                return Statement::error(
136                    token,
137                    "Expected identifier after 'as' in load statement".to_string()
138                );
139            }
140
141            let alias = as_token.lexeme.clone();
142
143            parser.advance(); // consume identifier
144
145            Statement {
146                kind: StatementKind::Load {
147                    source: path,
148                    alias,
149                },
150                value: Value::Null,
151                indent: token.indent,
152                line: token.line,
153                column: token.column,
154            }
155        }
156
157        _ => {
158            let message = format!("Unknown keyword after '@' : {}", keyword);
159            Statement::error(token, message)
160        }
161    }
162}