1use super::lexer::{Token, TokenType};
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum Expr {
7 Null,
8 Bool(bool),
9 Number(f64),
10 String(String),
11 Identifier(String),
12 Array(Vec<Expr>),
13 Object(Vec<(String, Expr)>),
14 Binary {
15 left: Box<Expr>,
16 op: BinaryOp,
17 right: Box<Expr>,
18 },
19 Unary {
20 op: UnaryOp,
21 expr: Box<Expr>,
22 },
23 Call {
24 callee: Box<Expr>,
25 args: Vec<Expr>,
26 },
27 Index {
28 object: Box<Expr>,
29 index: Box<Expr>,
30 },
31 Member {
32 object: Box<Expr>,
33 property: String,
34 },
35 Assign {
36 target: Box<Expr>,
37 value: Box<Expr>,
38 },
39 Lambda {
40 params: Vec<String>,
41 body: Vec<Stmt>,
42 },
43}
44
45#[derive(Debug, Clone, PartialEq)]
46pub enum BinaryOp {
47 Add, Sub, Mul, Div, Mod,
48 Eq, Neq, Lt, Gt, Lte, Gte,
49 And, Or,
50}
51
52#[derive(Debug, Clone, PartialEq)]
53pub enum UnaryOp {
54 Neg, Not,
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub enum Stmt {
59 Expr(Expr),
60 Let {
61 name: String,
62 value: Expr,
63 },
64 Const {
65 name: String,
66 value: Expr,
67 },
68 Fn {
69 name: String,
70 params: Vec<String>,
71 body: Vec<Stmt>,
72 },
73 Block(Vec<Stmt>),
74 If {
75 condition: Expr,
76 then_branch: Vec<Stmt>,
77 else_branch: Option<Vec<Stmt>>,
78 },
79 While {
80 condition: Expr,
81 body: Vec<Stmt>,
82 },
83 For {
84 var: String,
85 iterable: Expr,
86 body: Vec<Stmt>,
87 },
88 Return(Option<Expr>),
89 Break,
90 Continue,
91 Import {
92 path: String,
93 },
94}
95
96pub struct Parser {
97 tokens: Vec<Token>,
98 current: usize,
99}
100
101impl Parser {
102 pub fn new(tokens: Vec<Token>) -> Self {
103 Parser { tokens, current: 0 }
104 }
105
106 pub fn parse(&mut self) -> Result<Vec<Stmt>, String> {
107 let mut stmts = Vec::new();
108 while !self.is_at_end() {
109 if self.match_token(&[TokenType::Newline]) || self.match_token(&[TokenType::Comment(String::new())]) {
110 continue;
111 }
112 stmts.push(self.statement()?);
113 }
114 Ok(stmts)
115 }
116
117 fn statement(&mut self) -> Result<Stmt, String> {
118 if self.match_token(&[TokenType::Import]) {
119 self.import_statement()
120 } else if self.match_token(&[TokenType::Let]) {
121 self.let_statement()
122 } else if self.match_token(&[TokenType::Const]) {
123 self.const_statement()
124 } else if self.match_token(&[TokenType::Fn]) {
125 self.fn_statement()
126 } else if self.match_token(&[TokenType::If]) {
127 self.if_statement()
128 } else if self.match_token(&[TokenType::While]) {
129 self.while_statement()
130 } else if self.match_token(&[TokenType::For]) {
131 self.for_statement()
132 } else if self.match_token(&[TokenType::Return]) {
133 self.return_statement()
134 } else if self.match_token(&[TokenType::Break]) {
135 Ok(Stmt::Break)
136 } else if self.match_token(&[TokenType::Continue]) {
137 Ok(Stmt::Continue)
138 } else if self.check(&TokenType::LBrace) {
139 self.block()
140 } else {
141 let expr = self.expression()?;
142 self.consume_semicolon();
143 Ok(Stmt::Expr(expr))
144 }
145 }
146
147 fn import_statement(&mut self) -> Result<Stmt, String> {
148 let path = match self.peek_token_type() {
149 Some(TokenType::String(s)) => {
150 let s = s.clone();
151 self.advance();
152 s
153 }
154 _ => return Err(format!("Expected string path after 'import' at line {}", self.peek().line)),
155 };
156 self.consume_semicolon();
157 Ok(Stmt::Import { path })
158 }
159
160 fn let_statement(&mut self) -> Result<Stmt, String> {
161 let name = self.consume_identifier("Expected variable name after 'let'")?;
162 self.consume(&TokenType::Assign, "Expected '=' after variable name")?;
163 let value = self.expression()?;
164 self.consume_semicolon();
165 Ok(Stmt::Let { name, value })
166 }
167
168 fn const_statement(&mut self) -> Result<Stmt, String> {
169 let name = self.consume_identifier("Expected constant name after 'const'")?;
170 self.consume(&TokenType::Assign, "Expected '=' after constant name")?;
171 let value = self.expression()?;
172 self.consume_semicolon();
173 Ok(Stmt::Const { name, value })
174 }
175
176 fn fn_statement(&mut self) -> Result<Stmt, String> {
177 let name = self.consume_identifier("Expected function name after 'fn'")?;
178 self.consume(&TokenType::LParen, "Expected '(' after function name")?;
179 let mut params = Vec::new();
180 if !self.check(&TokenType::RParen) {
181 loop {
182 params.push(self.consume_identifier("Expected parameter name")?);
183 if !self.match_token(&[TokenType::Comma]) {
184 break;
185 }
186 }
187 }
188 self.consume(&TokenType::RParen, "Expected ')' after parameters")?;
189 let body = self.block()?;
190 let body = match body {
191 Stmt::Block(stmts) => stmts,
192 _ => vec![body],
193 };
194 Ok(Stmt::Fn { name, params, body })
195 }
196
197 fn if_statement(&mut self) -> Result<Stmt, String> {
198 let condition = self.expression()?;
199 let then_branch = match self.block()? {
200 Stmt::Block(stmts) => stmts,
201 s => vec![s],
202 };
203 let else_branch = if self.match_token(&[TokenType::Else]) {
204 if self.check(&TokenType::If) {
205 Some(vec![self.if_statement()?])
206 } else {
207 Some(match self.block()? {
208 Stmt::Block(stmts) => stmts,
209 s => vec![s],
210 })
211 }
212 } else {
213 None
214 };
215 Ok(Stmt::If { condition, then_branch, else_branch })
216 }
217
218 fn while_statement(&mut self) -> Result<Stmt, String> {
219 let condition = self.expression()?;
220 let body = match self.block()? {
221 Stmt::Block(stmts) => stmts,
222 s => vec![s],
223 };
224 Ok(Stmt::While { condition, body })
225 }
226
227 fn for_statement(&mut self) -> Result<Stmt, String> {
228 let var = self.consume_identifier("Expected variable name after 'for'")?;
229 self.consume(&TokenType::In, "Expected 'in' after for variable")?;
230 let iterable = self.expression()?;
231 let body = match self.block()? {
232 Stmt::Block(stmts) => stmts,
233 s => vec![s],
234 };
235 Ok(Stmt::For { var, iterable, body })
236 }
237
238 fn return_statement(&mut self) -> Result<Stmt, String> {
239 let value = if self.check(&TokenType::Semicolon) || self.check(&TokenType::Newline) || self.check(&TokenType::RBrace) || self.is_at_end() {
240 None
241 } else {
242 Some(self.expression()?)
243 };
244 self.consume_semicolon();
245 Ok(Stmt::Return(value))
246 }
247
248 fn block(&mut self) -> Result<Stmt, String> {
249 self.consume(&TokenType::LBrace, "Expected '{'")?;
250 let mut stmts = Vec::new();
251 while !self.check(&TokenType::RBrace) && !self.is_at_end() {
252 if self.match_token(&[TokenType::Newline]) || self.match_token(&[TokenType::Comment(String::new())]) {
253 continue;
254 }
255 stmts.push(self.statement()?);
256 }
257 self.consume(&TokenType::RBrace, "Expected '}' after block")?;
258 Ok(Stmt::Block(stmts))
259 }
260
261 fn expression(&mut self) -> Result<Expr, String> {
262 self.assignment()
263 }
264
265 fn assignment(&mut self) -> Result<Expr, String> {
266 let expr = self.or()?;
267 if self.match_token(&[TokenType::Assign, TokenType::PlusAssign, TokenType::MinusAssign, TokenType::StarAssign, TokenType::SlashAssign]) {
268 let op = self.previous().token_type.clone();
269 let value = self.assignment()?;
270 match expr {
271 Expr::Identifier(name) => {
272 let value = match op {
273 TokenType::PlusAssign => Expr::Binary { left: Box::new(Expr::Identifier(name.clone())), op: BinaryOp::Add, right: Box::new(value) },
274 TokenType::MinusAssign => Expr::Binary { left: Box::new(Expr::Identifier(name.clone())), op: BinaryOp::Sub, right: Box::new(value) },
275 TokenType::StarAssign => Expr::Binary { left: Box::new(Expr::Identifier(name.clone())), op: BinaryOp::Mul, right: Box::new(value) },
276 TokenType::SlashAssign => Expr::Binary { left: Box::new(Expr::Identifier(name.clone())), op: BinaryOp::Div, right: Box::new(value) },
277 _ => value,
278 };
279 Ok(Expr::Assign { target: Box::new(Expr::Identifier(name)), value: Box::new(value) })
280 }
281 Expr::Member { object, property } => {
282 Ok(Expr::Assign { target: Box::new(Expr::Member { object, property }), value: Box::new(value) })
283 }
284 Expr::Index { object, index } => {
285 Ok(Expr::Assign { target: Box::new(Expr::Index { object, index }), value: Box::new(value) })
286 }
287 _ => Err("Invalid assignment target".to_string()),
288 }
289 } else {
290 Ok(expr)
291 }
292 }
293
294 fn or(&mut self) -> Result<Expr, String> {
295 let mut expr = self.and()?;
296 while self.match_token(&[TokenType::Or]) {
297 let right = self.and()?;
298 expr = Expr::Binary { left: Box::new(expr), op: BinaryOp::Or, right: Box::new(right) };
299 }
300 Ok(expr)
301 }
302
303 fn and(&mut self) -> Result<Expr, String> {
304 let mut expr = self.equality()?;
305 while self.match_token(&[TokenType::And]) {
306 let right = self.equality()?;
307 expr = Expr::Binary { left: Box::new(expr), op: BinaryOp::And, right: Box::new(right) };
308 }
309 Ok(expr)
310 }
311
312 fn equality(&mut self) -> Result<Expr, String> {
313 let mut expr = self.comparison()?;
314 while self.match_token(&[TokenType::Eq, TokenType::Neq]) {
315 let op = match self.previous().token_type {
316 TokenType::Eq => BinaryOp::Eq,
317 TokenType::Neq => BinaryOp::Neq,
318 _ => unreachable!(),
319 };
320 let right = self.comparison()?;
321 expr = Expr::Binary { left: Box::new(expr), op, right: Box::new(right) };
322 }
323 Ok(expr)
324 }
325
326 fn comparison(&mut self) -> Result<Expr, String> {
327 let mut expr = self.term()?;
328 while self.match_token(&[TokenType::Lt, TokenType::Gt, TokenType::Lte, TokenType::Gte]) {
329 let op = match self.previous().token_type {
330 TokenType::Lt => BinaryOp::Lt,
331 TokenType::Gt => BinaryOp::Gt,
332 TokenType::Lte => BinaryOp::Lte,
333 TokenType::Gte => BinaryOp::Gte,
334 _ => unreachable!(),
335 };
336 let right = self.term()?;
337 expr = Expr::Binary { left: Box::new(expr), op, right: Box::new(right) };
338 }
339 Ok(expr)
340 }
341
342 fn term(&mut self) -> Result<Expr, String> {
343 let mut expr = self.factor()?;
344 while self.match_token(&[TokenType::Plus, TokenType::Minus]) {
345 let op = match self.previous().token_type {
346 TokenType::Plus => BinaryOp::Add,
347 TokenType::Minus => BinaryOp::Sub,
348 _ => unreachable!(),
349 };
350 let right = self.factor()?;
351 expr = Expr::Binary { left: Box::new(expr), op, right: Box::new(right) };
352 }
353 Ok(expr)
354 }
355
356 fn factor(&mut self) -> Result<Expr, String> {
357 let mut expr = self.unary()?;
358 while self.match_token(&[TokenType::Star, TokenType::Slash, TokenType::Percent]) {
359 let op = match self.previous().token_type {
360 TokenType::Star => BinaryOp::Mul,
361 TokenType::Slash => BinaryOp::Div,
362 TokenType::Percent => BinaryOp::Mod,
363 _ => unreachable!(),
364 };
365 let right = self.unary()?;
366 expr = Expr::Binary { left: Box::new(expr), op, right: Box::new(right) };
367 }
368 Ok(expr)
369 }
370
371 fn unary(&mut self) -> Result<Expr, String> {
372 if self.match_token(&[TokenType::Minus, TokenType::Not]) {
373 let op = match self.previous().token_type {
374 TokenType::Minus => UnaryOp::Neg,
375 TokenType::Not => UnaryOp::Not,
376 _ => unreachable!(),
377 };
378 let expr = self.unary()?;
379 Ok(Expr::Unary { op, expr: Box::new(expr) })
380 } else {
381 self.call()
382 }
383 }
384
385 fn call(&mut self) -> Result<Expr, String> {
386 let mut expr = self.primary()?;
387 loop {
388 if self.match_token(&[TokenType::LParen]) {
389 let mut args = Vec::new();
390 if !self.check(&TokenType::RParen) {
391 loop {
392 args.push(self.expression()?);
393 if !self.match_token(&[TokenType::Comma]) {
394 break;
395 }
396 }
397 }
398 self.consume(&TokenType::RParen, "Expected ')' after arguments")?;
399 expr = Expr::Call { callee: Box::new(expr), args };
400 } else if self.match_token(&[TokenType::Dot]) {
401 let property = self.consume_identifier("Expected property name after '.'")?;
402 expr = Expr::Member { object: Box::new(expr), property };
403 } else if self.match_token(&[TokenType::LBracket]) {
404 let index = self.expression()?;
405 self.consume(&TokenType::RBracket, "Expected ']' after index")?;
406 expr = Expr::Index { object: Box::new(expr), index: Box::new(index) };
407 } else {
408 break;
409 }
410 }
411 Ok(expr)
412 }
413
414 fn primary(&mut self) -> Result<Expr, String> {
415 if self.match_token(&[TokenType::Null]) {
416 Ok(Expr::Null)
417 } else if self.match_token(&[TokenType::Bool(true)]) {
418 Ok(Expr::Bool(true))
419 } else if self.match_token(&[TokenType::Bool(false)]) {
420 Ok(Expr::Bool(false))
421 } else if let Some(TokenType::Number(n)) = self.peek_token_type() {
422 let n = *n;
423 self.advance();
424 Ok(Expr::Number(n))
425 } else if let Some(TokenType::String(s)) = self.peek_token_type() {
426 let s = s.clone();
427 self.advance();
428 Ok(Expr::String(s))
429 } else if self.match_token(&[TokenType::LBracket]) {
430 let mut elements = Vec::new();
431 if !self.check(&TokenType::RBracket) {
432 loop {
433 elements.push(self.expression()?);
434 if !self.match_token(&[TokenType::Comma]) {
435 break;
436 }
437 }
438 }
439 self.consume(&TokenType::RBracket, "Expected ']' after array elements")?;
440 Ok(Expr::Array(elements))
441 } else if self.match_token(&[TokenType::LBrace]) {
442 let mut pairs = Vec::new();
443 if !self.check(&TokenType::RBrace) {
444 loop {
445 let key = self.consume_identifier("Expected object key")?;
446 self.consume(&TokenType::Colon, "Expected ':' after object key")?;
447 let value = self.expression()?;
448 pairs.push((key, value));
449 if !self.match_token(&[TokenType::Comma]) {
450 break;
451 }
452 }
453 }
454 self.consume(&TokenType::RBrace, "Expected '}' after object pairs")?;
455 Ok(Expr::Object(pairs))
456 } else if self.match_token(&[TokenType::Fn]) {
457 self.consume(&TokenType::LParen, "Expected '(' after 'fn'")?;
458 let mut params = Vec::new();
459 if !self.check(&TokenType::RParen) {
460 loop {
461 params.push(self.consume_identifier("Expected parameter name")?);
462 if !self.match_token(&[TokenType::Comma]) {
463 break;
464 }
465 }
466 }
467 self.consume(&TokenType::RParen, "Expected ')' after parameters")?;
468 let body = match self.block()? {
469 Stmt::Block(stmts) => stmts,
470 s => vec![s],
471 };
472 Ok(Expr::Lambda { params, body })
473 } else if let Some(TokenType::Identifier(name)) = self.peek_token_type() {
474 let name = name.clone();
475 self.advance();
476 Ok(Expr::Identifier(name))
477 } else {
478 Err(format!("Unexpected token: {:?}", self.peek()))
479 }
480 }
481
482 fn match_token(&mut self, types: &[TokenType]) -> bool {
484 for t in types {
485 if self.check(t) {
486 self.advance();
487 return true;
488 }
489 }
490 false
491 }
492
493 fn check(&self, token_type: &TokenType) -> bool {
494 if self.is_at_end() {
495 return false;
496 }
497 match (&self.peek().token_type, token_type) {
498 (TokenType::Comment(_), TokenType::Comment(_)) => true,
499 (a, b) => std::mem::discriminant(a) == std::mem::discriminant(b),
500 }
501 }
502
503 fn advance(&mut self) -> &Token {
504 if !self.is_at_end() {
505 self.current += 1;
506 }
507 self.previous()
508 }
509
510 fn is_at_end(&self) -> bool {
511 matches!(self.peek().token_type, TokenType::Eof)
512 }
513
514 fn peek(&self) -> &Token {
515 &self.tokens[self.current]
516 }
517
518 fn peek_token_type(&self) -> Option<&TokenType> {
519 if self.is_at_end() {
520 None
521 } else {
522 Some(&self.peek().token_type)
523 }
524 }
525
526 fn previous(&self) -> &Token {
527 &self.tokens[self.current - 1]
528 }
529
530 fn consume(&mut self, token_type: &TokenType, message: &str) -> Result<(), String> {
531 if self.check(token_type) {
532 self.advance();
533 Ok(())
534 } else {
535 Err(format!("{} at line {}, column {} (got {:?})",
536 message, self.peek().line, self.peek().column, self.peek().token_type))
537 }
538 }
539
540 fn consume_identifier(&mut self, message: &str) -> Result<String, String> {
541 if let Some(TokenType::Identifier(name)) = self.peek_token_type() {
542 let name = name.clone();
543 self.advance();
544 Ok(name)
545 } else {
546 Err(format!("{} at line {}, column {} (got {:?})",
547 message, self.peek().line, self.peek().column, self.peek().token_type))
548 }
549 }
550
551 fn consume_semicolon(&mut self) {
552 self.match_token(&[TokenType::Semicolon]);
553 }
554}
555
556pub fn parse(tokens: &[Token]) -> Result<Vec<Stmt>, String> {
557 let mut parser = Parser::new(tokens.to_vec());
558 parser.parse()
559}
560