1use std::fmt;
8
9use anyhow::{Result, anyhow};
10use itertools::Itertools;
11
12#[derive(Debug, Clone, PartialEq)]
14pub enum Expression {
15 Variable(String),
17
18 FieldAccess {
20 base: Box<Expression>,
21 field: String,
22 },
23
24 Index {
26 base: Box<Expression>,
27 index: Box<Expression>,
28 },
29
30 Deref(Box<Expression>),
32
33 AddressOf {
35 mutable: bool,
36 expr: Box<Expression>,
37 },
38
39 NumberLiteral(u64),
41
42 StringLiteral(String),
44
45 Parenthesized(Box<Expression>),
47
48 MethodCall {
50 base: Box<Expression>,
51 method: String,
52 args: Vec<Expression>,
53 },
54
55 FunctionCall {
57 function: String,
58 args: Vec<Expression>,
59 },
60}
61
62impl fmt::Display for Expression {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 match self {
65 Expression::Variable(name) => write!(f, "{name}"),
66 Expression::FieldAccess { base, field } => write!(f, "{base}.{field}"),
67 Expression::Index { base, index } => write!(f, "{base}[{index}]"),
68 Expression::Deref(expr) => write!(f, "*{expr}"),
69 Expression::AddressOf { mutable, expr } => {
70 if *mutable {
71 write!(f, "&mut {expr}")
72 } else {
73 write!(f, "&{expr}")
74 }
75 }
76 Expression::NumberLiteral(value) => write!(f, "{value}"),
77 Expression::StringLiteral(value) => write!(f, "\"{value}\""),
78 Expression::Parenthesized(expr) => write!(f, "({expr})"),
79 Expression::MethodCall { base, method, args } => {
80 write!(f, "{base}.{method}({})", args.iter().join(", "))
81 }
82 Expression::FunctionCall { function, args } => {
83 write!(f, "{function}({})", args.iter().join(", "))
84 }
85 }
86 }
87}
88
89#[derive(Debug, Clone, PartialEq)]
91enum Token {
92 Identifier(String),
93 Number(u64),
94 String(String),
95 Dot,
96 Star,
97 Ampersand,
98 LeftBracket,
100 RightBracket,
102 LeftParen,
104 RightParen,
106 Comma,
108 Mut,
109 Eof,
110}
111
112struct Tokenizer<'a> {
113 input: &'a str,
114 position: usize,
115}
116
117impl<'a> Tokenizer<'a> {
118 fn new(input: &'a str) -> Self {
119 Self { input, position: 0 }
120 }
121
122 fn current_char(&self) -> Option<char> {
123 self.input.chars().nth(self.position)
124 }
125
126 fn advance(&mut self) {
127 if self.position < self.input.len() {
128 self.position += 1;
129 }
130 }
131
132 fn skip_whitespace(&mut self) {
133 while let Some(ch) = self.current_char() {
134 if ch.is_whitespace() {
135 self.advance();
136 } else {
137 break;
138 }
139 }
140 }
141
142 fn read_identifier(&mut self) -> String {
143 let start = self.position;
144 while let Some(ch) = self.current_char() {
145 if ch.is_ascii_alphanumeric() || ch == '_' {
146 self.advance();
147 } else {
148 break;
149 }
150 }
151 self.input[start..self.position].to_string()
152 }
153
154 fn read_number(&mut self) -> Result<u64> {
155 let start = self.position;
156
157 if self.input[self.position..].starts_with("0x")
159 || self.input[self.position..].starts_with("0X")
160 {
161 self.advance(); self.advance(); while let Some(ch) = self.current_char() {
164 if ch.is_ascii_hexdigit() {
165 self.advance();
166 } else {
167 break;
168 }
169 }
170 let hex_str = &self.input[start + 2..self.position];
171 u64::from_str_radix(hex_str, 16).map_err(|e| anyhow!("Invalid hex number: {}", e))
172 } else {
173 while let Some(ch) = self.current_char() {
175 if ch.is_ascii_digit() {
176 self.advance();
177 } else {
178 break;
179 }
180 }
181 self.input[start..self.position]
182 .parse()
183 .map_err(|e| anyhow!("Invalid number: {}", e))
184 }
185 }
186
187 fn read_string(&mut self) -> Result<String> {
188 self.advance();
190 let start = self.position;
191
192 while let Some(ch) = self.current_char() {
193 if ch == '"' {
194 let content = self.input[start..self.position].to_string();
196 self.advance(); return Ok(content);
198 } else if ch == '\\' {
199 self.advance(); if self.current_char().is_some() {
202 self.advance(); }
204 } else {
205 self.advance();
206 }
207 }
208
209 Err(anyhow!("Unterminated string literal"))
210 }
211
212 fn next_token(&mut self) -> Result<Token> {
213 self.skip_whitespace();
214
215 match self.current_char() {
216 None => Ok(Token::Eof),
217 Some('.') => {
218 self.advance();
219 Ok(Token::Dot)
220 }
221 Some('*') => {
222 self.advance();
223 Ok(Token::Star)
224 }
225 Some('&') => {
226 self.advance();
227 Ok(Token::Ampersand)
228 }
229 Some('[') => {
230 self.advance();
231 Ok(Token::LeftBracket)
232 }
233 Some(']') => {
234 self.advance();
235 Ok(Token::RightBracket)
236 }
237 Some('(') => {
238 self.advance();
239 Ok(Token::LeftParen)
240 }
241 Some(')') => {
242 self.advance();
243 Ok(Token::RightParen)
244 }
245 Some(',') => {
246 self.advance();
247 Ok(Token::Comma)
248 }
249 Some(ch) if ch.is_ascii_alphabetic() || ch == '_' => {
250 let ident = self.read_identifier();
251 if ident == "mut" {
252 Ok(Token::Mut)
253 } else {
254 Ok(Token::Identifier(ident))
255 }
256 }
257 Some(ch) if ch.is_ascii_digit() => {
258 let number = self.read_number()?;
259 Ok(Token::Number(number))
260 }
261 Some('"') => {
262 let string = self.read_string()?;
263 Ok(Token::String(string))
264 }
265 Some(ch) => Err(anyhow!("Unexpected character: '{}'", ch)),
266 }
267 }
268}
269
270struct Parser {
272 tokens: Vec<Token>,
273 position: usize,
274}
275
276impl Parser {
277 fn new(input: &str) -> Result<Self> {
278 let mut tokenizer = Tokenizer::new(input);
279 let mut tokens = Vec::new();
280
281 loop {
282 let token = tokenizer.next_token()?;
283 let is_eof = token == Token::Eof;
284 tokens.push(token);
285 if is_eof {
286 break;
287 }
288 }
289
290 Ok(Self {
291 tokens,
292 position: 0,
293 })
294 }
295
296 fn current_token(&self) -> &Token {
297 self.tokens.get(self.position).unwrap_or(&Token::Eof)
298 }
299
300 fn advance(&mut self) {
301 if self.position < self.tokens.len() {
302 self.position += 1;
303 }
304 }
305
306 fn expect(&mut self, expected: Token) -> Result<()> {
307 if std::mem::discriminant(self.current_token()) == std::mem::discriminant(&expected) {
308 self.advance();
309 Ok(())
310 } else {
311 Err(anyhow!(
312 "Expected {:?}, found {:?}",
313 expected,
314 self.current_token()
315 ))
316 }
317 }
318
319 pub fn parse(&mut self) -> Result<Expression> {
320 self.parse_expression()
321 }
322
323 fn parse_expression(&mut self) -> Result<Expression> {
324 self.parse_unary()
325 }
326
327 fn parse_unary(&mut self) -> Result<Expression> {
328 match self.current_token() {
329 Token::Star => {
330 self.advance();
331 let expr = self.parse_unary()?;
332 Ok(Expression::Deref(Box::new(expr)))
333 }
334 Token::Ampersand => {
335 self.advance();
336 let mutable = matches!(self.current_token(), Token::Mut);
337 if mutable {
338 self.advance();
339 }
340 let expr = self.parse_unary()?;
341 Ok(Expression::AddressOf {
342 mutable,
343 expr: Box::new(expr),
344 })
345 }
346 _ => self.parse_postfix(),
347 }
348 }
349
350 fn parse_postfix(&mut self) -> Result<Expression> {
351 let mut expr = self.parse_primary()?;
352
353 loop {
354 match self.current_token() {
355 Token::Dot => {
356 self.advance();
357 if let Token::Identifier(field) = self.current_token() {
358 let field = field.clone();
359 self.advance();
360
361 if matches!(self.current_token(), Token::LeftParen) {
363 self.advance(); let args = self.parse_arguments()?;
365 self.expect(Token::RightParen)?;
366 expr = Expression::MethodCall {
367 base: Box::new(expr),
368 method: field,
369 args,
370 };
371 } else {
372 expr = Expression::FieldAccess {
373 base: Box::new(expr),
374 field,
375 };
376 }
377 } else {
378 return Err(anyhow!("Expected field name after '.'"));
379 }
380 }
381 Token::LeftBracket => {
382 self.advance();
383 let index = self.parse_expression()?;
384 self.expect(Token::RightBracket)?;
385 expr = Expression::Index {
386 base: Box::new(expr),
387 index: Box::new(index),
388 };
389 }
390 _ => break,
391 }
392 }
393
394 Ok(expr)
395 }
396
397 fn parse_primary(&mut self) -> Result<Expression> {
398 match self.current_token() {
399 Token::Identifier(name) => {
400 let name = name.clone();
401 self.advance();
402
403 if matches!(self.current_token(), Token::LeftParen) {
405 self.advance(); let args = self.parse_arguments()?;
407 self.expect(Token::RightParen)?;
408 Ok(Expression::FunctionCall {
409 function: name,
410 args,
411 })
412 } else {
413 Ok(Expression::Variable(name))
414 }
415 }
416 Token::Number(value) => {
417 let value = *value;
418 self.advance();
419 Ok(Expression::NumberLiteral(value))
420 }
421 Token::String(value) => {
422 let value = value.clone();
423 self.advance();
424 Ok(Expression::StringLiteral(value))
425 }
426 Token::LeftParen => {
427 self.advance();
428 let expr = self.parse_expression()?;
429 self.expect(Token::RightParen)?;
430 Ok(Expression::Parenthesized(Box::new(expr)))
431 }
432 _ => Err(anyhow!(
433 "Expected identifier, number, string, or '(', found {:?}",
434 self.current_token()
435 )),
436 }
437 }
438
439 fn parse_arguments(&mut self) -> Result<Vec<Expression>> {
440 let mut args = Vec::new();
441
442 if matches!(self.current_token(), Token::RightParen) {
444 return Ok(args);
445 }
446
447 args.push(self.parse_expression()?);
449
450 while matches!(self.current_token(), Token::Comma) {
452 self.advance(); args.push(self.parse_expression()?);
454 }
455
456 Ok(args)
457 }
458}
459
460pub fn parse_expression(input: &str) -> Result<Expression> {
462 let mut parser = Parser::new(input)?;
463 parser.parse()
464}
465
466#[cfg(test)]
467mod tests {
468 use super::*;
469
470 #[track_caller]
471 fn parse(s: &str) -> Expression {
472 match parse_expression(s) {
473 Ok(expr) => expr,
474 Err(e) => panic!("Failed to parse expression '{s}': {e}"),
475 }
476 }
477
478 #[test]
479 fn test_variable() {
480 let expr = parse("foo");
481 assert_eq!(expr, Expression::Variable("foo".to_string()));
482 }
483
484 #[test]
485 fn test_number_literal() {
486 let expr = parse("42");
487 assert_eq!(expr, Expression::NumberLiteral(42));
488
489 let expr = parse("0xff");
490 assert_eq!(expr, Expression::NumberLiteral(0xff));
491 }
492
493 #[test]
494 fn test_string_literal() {
495 let expr = parse(r#""hello""#);
496 assert_eq!(expr, Expression::StringLiteral("hello".to_string()));
497
498 let expr = parse(r#""created""#);
499 assert_eq!(expr, Expression::StringLiteral("created".to_string()));
500 }
501
502 #[test]
503 fn test_field_access() {
504 let expr = parse("foo.bar");
505 assert_eq!(
506 expr,
507 Expression::FieldAccess {
508 base: Box::new(Expression::Variable("foo".to_string())),
509 field: "bar".to_string(),
510 }
511 );
512 }
513
514 #[test]
515 fn test_chained_field_access() {
516 let expr = parse("foo.bar.baz");
517 assert_eq!(
518 expr,
519 Expression::FieldAccess {
520 base: Box::new(Expression::FieldAccess {
521 base: Box::new(Expression::Variable("foo".to_string())),
522 field: "bar".to_string(),
523 }),
524 field: "baz".to_string(),
525 }
526 );
527 }
528
529 #[test]
530 fn test_index_access() {
531 let expr = parse("arr[0]");
532 assert_eq!(
533 expr,
534 Expression::Index {
535 base: Box::new(Expression::Variable("arr".to_string())),
536 index: Box::new(Expression::NumberLiteral(0)),
537 }
538 );
539
540 let expr = parse(r#"map["key"]"#);
542 assert_eq!(
543 expr,
544 Expression::Index {
545 base: Box::new(Expression::Variable("map".to_string())),
546 index: Box::new(Expression::StringLiteral("key".to_string())),
547 }
548 );
549 }
550
551 #[test]
552 fn test_deref() {
553 let expr = parse("*ptr");
554 assert_eq!(
555 expr,
556 Expression::Deref(Box::new(Expression::Variable("ptr".to_string())))
557 );
558 }
559
560 #[test]
561 fn test_address_of() {
562 let expr = parse("&var");
563 assert_eq!(
564 expr,
565 Expression::AddressOf {
566 mutable: false,
567 expr: Box::new(Expression::Variable("var".to_string())),
568 }
569 );
570
571 let expr = parse("&mut var");
572 assert_eq!(
573 expr,
574 Expression::AddressOf {
575 mutable: true,
576 expr: Box::new(Expression::Variable("var".to_string())),
577 }
578 );
579 }
580
581 #[test]
582 fn test_parenthesized() {
583 let expr = parse("(foo)");
584 assert_eq!(
585 expr,
586 Expression::Parenthesized(Box::new(Expression::Variable("foo".to_string())))
587 );
588 }
589
590 #[test]
591 fn test_complex_expressions() {
592 let expr = parse("obj.field[0]");
594 assert_eq!(
595 expr,
596 Expression::Index {
597 base: Box::new(Expression::FieldAccess {
598 base: Box::new(Expression::Variable("obj".to_string())),
599 field: "field".to_string(),
600 }),
601 index: Box::new(Expression::NumberLiteral(0)),
602 }
603 );
604
605 let expr = parse("*obj.ptr");
607 assert_eq!(
608 expr,
609 Expression::Deref(Box::new(Expression::FieldAccess {
610 base: Box::new(Expression::Variable("obj".to_string())),
611 field: "ptr".to_string(),
612 }))
613 );
614 }
615
616 #[test]
617 fn test_display_formatting() {
618 assert_eq!(parse("foo").to_string(), "foo");
619 assert_eq!(parse("42").to_string(), "42");
620 assert_eq!(parse(r#""hello""#).to_string(), r#""hello""#);
621 assert_eq!(parse("foo.bar").to_string(), "foo.bar");
622 assert_eq!(parse("arr[0]").to_string(), "arr[0]");
623 assert_eq!(parse(r#"map["key"]"#).to_string(), r#"map["key"]"#);
624 assert_eq!(parse("*ptr").to_string(), "*ptr");
625 assert_eq!(parse("&var").to_string(), "&var");
626 assert_eq!(parse("&mut var").to_string(), "&mut var");
627 assert_eq!(parse("(foo)").to_string(), "(foo)");
628 }
629
630 #[test]
631 fn test_method_call() {
632 let expr = parse("vec.len()");
634 assert_eq!(
635 expr,
636 Expression::MethodCall {
637 base: Box::new(Expression::Variable("vec".to_string())),
638 method: "len".to_string(),
639 args: vec![],
640 }
641 );
642
643 let expr = parse("vec.push(42)");
645 assert_eq!(
646 expr,
647 Expression::MethodCall {
648 base: Box::new(Expression::Variable("vec".to_string())),
649 method: "push".to_string(),
650 args: vec![Expression::NumberLiteral(42)],
651 }
652 );
653
654 let expr = parse(r#"map.insert("key", 42)"#);
656 assert_eq!(
657 expr,
658 Expression::MethodCall {
659 base: Box::new(Expression::Variable("map".to_string())),
660 method: "insert".to_string(),
661 args: vec![
662 Expression::StringLiteral("key".to_string()),
663 Expression::NumberLiteral(42)
664 ],
665 }
666 );
667
668 let expr = parse("vec.iter().count()");
670 assert_eq!(
671 expr,
672 Expression::MethodCall {
673 base: Box::new(Expression::MethodCall {
674 base: Box::new(Expression::Variable("vec".to_string())),
675 method: "iter".to_string(),
676 args: vec![],
677 }),
678 method: "count".to_string(),
679 args: vec![],
680 }
681 );
682 }
683
684 #[test]
685 fn test_function_call() {
686 let expr = parse("foo()");
688 assert_eq!(
689 expr,
690 Expression::FunctionCall {
691 function: "foo".to_string(),
692 args: vec![],
693 }
694 );
695
696 let expr = parse("bar(1, 2)");
698 assert_eq!(
699 expr,
700 Expression::FunctionCall {
701 function: "bar".to_string(),
702 args: vec![Expression::NumberLiteral(1), Expression::NumberLiteral(2)],
703 }
704 );
705 }
706
707 #[test]
708 fn test_method_call_display() {
709 assert_eq!(parse("vec.len()").to_string(), "vec.len()");
710 assert_eq!(parse("vec.push(42)").to_string(), "vec.push(42)");
711 assert_eq!(
712 parse(r#"map.insert("key", 42)"#).to_string(),
713 r#"map.insert("key", 42)"#
714 );
715 assert_eq!(parse("foo()").to_string(), "foo()");
716 assert_eq!(parse("bar(1, 2)").to_string(), "bar(1, 2)");
717 }
718}