Skip to main content

dar_core/
parser.rs

1// crates/dar-core/src/parser.rs
2use crate::{ast::*, lexer::Lexer, token::Token};
3pub struct Parser {
4    lexer: Lexer,
5    current: Token,
6}
7impl Parser {
8    pub fn new(mut lexer: Lexer,) -> Result<Self, String,> {
9        let current = lexer.next_token()?;
10        Ok(Self { lexer, current, },)
11    }
12    fn advance(&mut self,) -> Result<(), String,> {
13        self.current = self.lexer.next_token()?;
14        Ok((),)
15    }
16    fn expect(&mut self, expected: Token,) -> Result<(), String,> {
17        if self.current == expected {
18            self.advance()
19        } else {
20            Err(format!("Expected {:?}, found {:?}", expected, self.current),)
21        }
22    }
23    pub fn parse(&mut self,) -> Result<Vec<Stmt,>, String,> {
24        let mut stmts = Vec::new();
25        while self.current != Token::Eof {
26            stmts.push(self.parse_stmt()?,);
27        }
28        Ok(stmts,)
29    }
30    fn parse_stmt(&mut self,) -> Result<Stmt, String,> {
31        match &self.current {
32            Token::KeywordText => self.parse_decl(),
33            Token::KeywordPrint => self.parse_print(),
34            Token::KeywordExternal => self.parse_external(),
35            Token::KeywordMod => self.parse_mod(),
36            Token::KeywordLua => self.parse_lua(),
37            Token::Identifier(name,) => {
38                let func = name.clone();
39                self.advance()?;
40                self.expect(Token::LParen,)?;
41                let arg = self.parse_expr()?;
42                self.expect(Token::RParen,)?;
43                Ok(Stmt::Call { func, arg, },)
44            },
45            _ => Err(format!("Unexpected token: {:?}", self.current),),
46        }
47    }
48    fn parse_decl(&mut self,) -> Result<Stmt, String,> {
49        self.advance()?; // 'text'
50        let name = match &self.current {
51            Token::Identifier(id,) => id.clone(),
52            _ => return Err("Expected identifier after 'text'".to_string(),),
53        };
54        self.advance()?;
55        let init = if self.current == Token::Equal {
56            self.advance()?;
57            Some(self.parse_expr()?,)
58        } else {
59            None
60        };
61        Ok(Stmt::Decl { name, init, },)
62    }
63    fn parse_name(&mut self,) -> Result<String, String,> {
64        match &self.current {
65            Token::Identifier(name,) => {
66                let n = name.clone();
67                self.advance()?;
68                Ok(n,)
69            },
70            Token::KeywordText => {
71                self.advance()?;
72                Ok("text".to_string(),)
73            },
74            Token::KeywordPrint => {
75                self.advance()?;
76                Ok("print".to_string(),)
77            },
78            Token::KeywordExternal => {
79                self.advance()?;
80                Ok("external".to_string(),)
81            },
82            Token::KeywordMod => {
83                self.advance()?;
84                Ok("mod".to_string(),)
85            },
86            Token::Upper => {
87                self.advance()?;
88                Ok("Upper".to_string(),)
89            },
90            Token::Empty => {
91                self.advance()?;
92                Ok("empty".to_string(),)
93            },
94            _ => Err(format!(
95                "Expected identifier or keyword, found {:?}",
96                self.current
97            ),),
98        }
99    }
100    fn parse_print(&mut self,) -> Result<Stmt, String,> {
101        self.advance()?; // 'print'
102        self.expect(Token::LParen,)?;
103        let expr = self.parse_expr()?;
104        self.expect(Token::RParen,)?;
105        Ok(Stmt::Print { expr, },)
106    }
107    fn parse_lua(&mut self,) -> Result<Stmt, String,> {
108        self.advance()?; // 'lua'
109        let path = match &self.current {
110            Token::StringLiteral(s,) => s.clone(),
111            _ => {
112                return Err(
113                    "Expected string literal with Lua script path".to_string(),
114                );
115            },
116        };
117        self.advance()?;
118        self.expect(Token::LBrace,)?;
119        let mut mappings = Vec::new();
120        while self.current != Token::RBrace && self.current != Token::Eof {
121            let dar_name = match &self.current {
122                Token::Identifier(id,) => id.clone(),
123                _ => {
124                    return Err("Expected DAR function name inside lua block"
125                        .to_string(),);
126                },
127            };
128            self.advance()?;
129            self.expect(Token::Colon,)?;
130            let lua_name = self.parse_name()?; // может быть идентификатор или ключевое слово
131            mappings.push((dar_name, lua_name,),);
132            if self.current == Token::Comma {
133                self.advance()?;
134                continue;
135            } else if self.current == Token::RBrace {
136                break;
137            } else {
138                return Err("Expected ',' or '}' in lua block".to_string(),);
139            }
140        }
141        self.expect(Token::RBrace,)?;
142        Ok(Stmt::Lua { path, mappings, },)
143    }
144    fn parse_external(&mut self,) -> Result<Stmt, String,> {
145        self.advance()?; // 'external'
146        let path = match &self.current {
147            Token::StringLiteral(s,) => s.clone(),
148            _ => {
149                return Err(
150                    "Expected string literal with library path".to_string(),
151                );
152            },
153        };
154        self.advance()?;
155        self.expect(Token::LBrace,)?;
156        let mut functions = Vec::new();
157        while self.current != Token::RBrace && self.current != Token::Eof {
158            let source_name = match &self.current {
159                Token::Identifier(id,) => id.clone(),
160                _ => {
161                    return Err("Expected function name inside external block"
162                        .to_string(),);
163                },
164            };
165            self.advance()?;
166            let alias = if self.current == Token::Colon {
167                self.advance()?;
168                Some(self.parse_name()?,)
169            } else {
170                None
171            };
172            functions.push(ExternalFunc { source_name, alias, },);
173            if self.current == Token::Comma {
174                self.advance()?;
175                continue;
176            } else if self.current == Token::RBrace {
177                break;
178            } else {
179                return Err(
180                    "Expected ',' or '}' in external block".to_string(),
181                );
182            }
183        }
184        self.expect(Token::RBrace,)?;
185        Ok(Stmt::External { path, functions, },)
186    }
187    fn parse_mod(&mut self,) -> Result<Stmt, String,> {
188        self.advance()?; // 'mod'
189        let path = match &self.current {
190            Token::StringLiteral(s,) => s.clone(),
191            _ => {
192                return Err(
193                    "Expected string literal with module path".to_string(),
194                );
195            },
196        };
197        self.advance()?;
198        Ok(Stmt::Mod { path, },)
199    }
200    fn parse_expr(&mut self,) -> Result<Expr, String,> {
201        let primary = self.parse_primary()?;
202        if self.current == Token::Dot {
203            self.advance()?;
204            match self.current {
205                Token::Upper => {
206                    self.advance()?;
207                    self.expect(Token::LParen,)?;
208                    self.expect(Token::RParen,)?;
209                    Ok(Expr::MethodCall {
210                        obj: Box::new(primary,),
211                        method: Method::Upper,
212                    },)
213                },
214                _ => Err("Only .Upper() method supported".to_string(),),
215            }
216        } else if self.current == Token::LParen {
217            match primary {
218                Expr::Variable(name,) => {
219                    self.advance()?; // '('
220                    let arg = Box::new(self.parse_expr()?,);
221                    self.expect(Token::RParen,)?;
222                    Ok(Expr::Call { func: name, arg, },)
223                },
224                _ => Err("Only direct function calls allowed".to_string(),),
225            }
226        } else {
227            Ok(primary,)
228        }
229    }
230    fn parse_primary(&mut self,) -> Result<Expr, String,> {
231        match &self.current {
232            Token::Identifier(id,) => {
233                let id = id.clone();
234                self.advance()?;
235                Ok(Expr::Variable(id,),)
236            },
237            Token::StringLiteral(s,) => {
238                let s = s.clone();
239                self.advance()?;
240                Ok(Expr::StringLiteral(s,),)
241            },
242            Token::Empty => {
243                self.advance()?;
244                Ok(Expr::EmptyLiteral,)
245            },
246            _ => Err(format!(
247                "Unexpected token in expression: {:?}",
248                self.current
249            ),),
250        }
251    }
252}