From 8856d733ad79b54294a6f3334bce7af785226abd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Fri, 30 Dec 2022 23:50:02 +0100
Subject: [PATCH] AST - Expression node + dumper trait

---
 src/ast.rs  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main.rs |  1 +
 2 files changed, 56 insertions(+)
 create mode 100644 src/ast.rs

diff --git a/src/ast.rs b/src/ast.rs
new file mode 100644
index 0000000..62080b2
--- /dev/null
+++ b/src/ast.rs
@@ -0,0 +1,55 @@
+use crate::tokens::{Token, TokenType};
+
+/// This trait should be implemented by nodes to allow AST dumps.
+pub trait AstDumper {
+    /// Dump the node as a string.
+    fn dump(&self) -> String;
+}
+
+/// An AST node that represents an expression.
+#[derive(Debug, Clone)]
+pub enum ExprNode {
+    /// Binary expression.
+    Binary {
+        left: Box<ExprNode>,
+        operator: Token,
+        right: Box<ExprNode>,
+    },
+
+    /// Unary expression.
+    Unary {
+        operator: Token,
+        right: Box<ExprNode>,
+    },
+
+    /// Grouping expression, containing a sub-expression.
+    Grouping { expression: Box<ExprNode> },
+
+    /// A litteral value, represented by the corresponding token.
+    Litteral { value: Token },
+}
+
+impl AstDumper for ExprNode {
+    fn dump(&self) -> String {
+        match self {
+            Self::Binary {
+                left,
+                operator,
+                right,
+            } => {
+                format!("( {} {} {} )", operator.lexeme, left.dump(), right.dump())
+            }
+            Self::Unary { operator, right } => {
+                format!("( {} {} )", operator.lexeme, right.dump())
+            }
+            Self::Grouping { expression } => {
+                format!("( {} )", expression.dump())
+            }
+            Self::Litteral { value } => match &value.token_type {
+                TokenType::String(s) => s.clone(),
+                TokenType::Number(n) => format!("{n}"),
+                _ => panic!("Unexpected token type for token {:#?}", value),
+            },
+        }
+    }
+}
diff --git a/src/main.rs b/src/main.rs
index e737b91..fe00d16 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+mod ast;
 mod errors;
 mod scanner;
 mod tokens;