slang_ir/
visitor.rs

1use crate::ast::{
2    AssignmentStatement, BinaryExpr, BlockExpr, ConditionalExpr, Expression, FunctionCallExpr,
3    FunctionDeclarationStmt, FunctionTypeExpr, IfStatement, LetStatement, LiteralExpr, ReturnStatement, Statement, TypeDefinitionStmt,
4    UnaryExpr, VariableExpr,
5};
6
7/// Trait implementing the visitor pattern for traversing the AST
8///
9/// This trait allows implementing different behaviors when traversing
10/// the AST, such as type checking, interpretation, or compilation.
11///
12/// The generic parameter T represents the return type of the visit methods.
13pub trait Visitor<T> {
14    /// Visit a general statement
15    fn visit_statement(&mut self, stmt: &Statement) -> T {
16        match stmt {
17            Statement::Let(let_stmt) => self.visit_let_statement(let_stmt),
18            Statement::Assignment(assign_stmt) => self.visit_assignment_statement(assign_stmt),
19            Statement::Expression(expr) => self.visit_expression_statement(expr),
20            Statement::TypeDefinition(type_def) => self.visit_type_definition_statement(type_def),
21            Statement::FunctionDeclaration(fn_decl) => {
22                self.visit_function_declaration_statement(fn_decl)
23            }
24            Statement::Return(return_stmt) => self.visit_return_statement(return_stmt),
25            Statement::If(if_stmt) => self.visit_if_statement(if_stmt),
26        }
27    }
28
29    /// Visit an expression statement
30    fn visit_expression_statement(&mut self, expr: &Expression) -> T;
31
32    /// Visit a variable declaration statement
33    fn visit_let_statement(&mut self, stmt: &LetStatement) -> T;
34
35    /// Visit a type definition statement
36    fn visit_type_definition_statement(&mut self, stmt: &TypeDefinitionStmt) -> T;
37
38    /// Visit a function declaration statement
39    fn visit_function_declaration_statement(&mut self, stmt: &FunctionDeclarationStmt) -> T;
40
41    /// Visit a return statement
42    fn visit_return_statement(&mut self, stmt: &ReturnStatement) -> T;
43
44    /// Visit a variable assignment statement
45    fn visit_assignment_statement(&mut self, stmt: &AssignmentStatement) -> T;
46
47    /// Visit a general expression
48    fn visit_expression(&mut self, expr: &Expression) -> T {
49        match expr {
50            Expression::Literal(lit) => self.visit_literal_expression(lit),
51            Expression::Binary(bin) => self.visit_binary_expression(bin),
52            Expression::Variable(var) => self.visit_variable_expression(var),
53            Expression::Unary(unary) => self.visit_unary_expression(unary),
54            Expression::Call(call) => self.visit_call_expression(call),
55            Expression::Conditional(cond) => self.visit_conditional_expression(cond),
56            Expression::Block(block) => self.visit_block_expression(block),
57            Expression::FunctionType(func_type) => self.visit_function_type_expression(func_type),
58        }
59    }
60
61    /// Visit a binary expression (e.g., a + b)
62    fn visit_binary_expression(&mut self, expr: &BinaryExpr) -> T;
63
64    /// Visit a unary expression (e.g., -x)
65    fn visit_unary_expression(&mut self, expr: &UnaryExpr) -> T;
66
67    /// Visit a literal expression (e.g., 42, "hello")
68    fn visit_literal_expression(&mut self, expr: &LiteralExpr) -> T;
69
70    /// Visit a variable reference expression
71    fn visit_variable_expression(&mut self, var_expr: &VariableExpr) -> T;
72
73    /// Visit a function call expression
74    fn visit_call_expression(&mut self, expr: &FunctionCallExpr) -> T;
75
76    /// Visit a conditional expression (if/else)
77    fn visit_conditional_expression(&mut self, expr: &ConditionalExpr) -> T;
78
79    /// Visit a block expression
80    fn visit_block_expression(&mut self, expr: &BlockExpr) -> T;
81
82    /// Visit a function type expression (e.g., fn(i32, string) -> string)
83    fn visit_function_type_expression(&mut self, expr: &FunctionTypeExpr) -> T;
84
85    /// Visit a conditional statement (if/else)
86    fn visit_if_statement(&mut self, stmt: &IfStatement) -> T;
87}