devalang_core/core/parser/handler/
at.rs1use 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(); 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(); 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(); 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(); 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(); parser.advance(); 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; } else if token.kind == TokenKind::RBrace {
92 break; } 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(); 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(); parser.advance(); 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(); 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}