deimos-lang/src/ast/walk.rs
2025-09-28 12:34:37 -05:00

146 lines
7.5 KiB
Rust

use crate::ast::children::{NodeInner, NodeRef};
pub fn walk_depth_first<F>(node: &dyn NodeInner, f: &mut F)
where
F: FnMut(NodeRef),
{
use NodeRef::*;
for child in node.children() {
match child {
Identifier(identifier) => walk_depth_first(identifier, f),
FullyQualifiedName(fqn) => {
walk_depth_first(fqn, f);
}
TypeUse(type_use) => walk_depth_first(type_use, f),
PrimitiveTypeUse(primitive_type_use) => walk_depth_first(primitive_type_use, f),
InterfaceOrClassTypeUse(interface_or_class_type_use) => {
walk_depth_first(interface_or_class_type_use, f)
}
TupleTypeUse(tuple_type_use) => walk_depth_first(tuple_type_use, f),
FunctionTypeUse(function_type_use) => walk_depth_first(function_type_use, f),
GenericArguments(generic_arguments) => walk_depth_first(generic_arguments, f),
GenericParameters(generic_parameters) => walk_depth_first(generic_parameters, f),
TupleArguments(tuple_arguments) => walk_depth_first(tuple_arguments, f),
ImplementsList(implements) => walk_depth_first(implements, f),
Parameters(parameters) => walk_depth_first(parameters, f),
Parameter(parameter) => walk_depth_first(parameter, f),
ReturnType(return_type) => walk_depth_first(return_type, f),
References(references) => walk_depth_first(references, f),
UseStatement(use_statement) => walk_depth_first(use_statement, f),
CompilationUnit(compilation_unit) => walk_depth_first(compilation_unit, f),
ModuleLevelDeclaration(module_level_declaration) => {
walk_depth_first(module_level_declaration, f)
}
InterfaceLevelDeclaration(interface_level_declaration) => {
walk_depth_first(interface_level_declaration, f)
}
ClassLevelDeclaration(class_level_declaration) => {
walk_depth_first(class_level_declaration, f)
}
ModuleDeclaration(module_declaration) => walk_depth_first(module_declaration, f),
InterfaceDeclaration(interface_declaration) => {
walk_depth_first(interface_declaration, f)
}
ClassDeclaration(class_declaration) => walk_depth_first(class_declaration, f),
FunctionDefinition(function_definition) => walk_depth_first(function_definition, f),
OperatorFunctionDefinition(operator_function_definition) => {
walk_depth_first(operator_function_definition, f)
}
PlatformFunctionDeclaration(platform_function_declaration) => {
walk_depth_first(platform_function_declaration, f)
}
InterfaceFunctionDeclaration(interface_function_declaration) => {
walk_depth_first(interface_function_declaration, f)
}
InterfaceOperatorFunctionDeclaration(interface_operator_function_declaration) => {
walk_depth_first(interface_operator_function_declaration, f)
}
FunctionBody(function_body) => walk_depth_first(function_body, f),
ClassConstructor(class_constructor) => walk_depth_first(class_constructor, f),
ClassConstructorParameter(class_constructor_parameter) => {
walk_depth_first(class_constructor_parameter, f)
}
PropertyDeclaration(property_declaration) => walk_depth_first(property_declaration, f),
FieldDeclaration(field_declaration) => walk_depth_first(field_declaration, f),
BlockStatement(block) => walk_depth_first(block, f),
Statement(statement) => walk_depth_first(statement, f),
VariableDeclarationStatement(variable_declaration) => {
walk_depth_first(variable_declaration, f)
}
AssignStatement(assign_statement) => walk_depth_first(assign_statement, f),
CallStatement(call_statement) => walk_depth_first(call_statement, f),
ReturnStatement(return_statement) => walk_depth_first(return_statement, f),
IfStatement(if_statement) => walk_depth_first(if_statement, f),
IfElseStatement(if_else_statement) => walk_depth_first(if_else_statement, f),
ElseIfs(else_ifs) => walk_depth_first(else_ifs, f),
ElseBlock(else_block) => walk_depth_first(else_block, f),
WhileStatement(while_statement) => walk_depth_first(while_statement, f),
ForStatement(for_statement) => walk_depth_first(for_statement, f),
Expression(expression) => walk_depth_first(expression, f),
TernaryExpression(ternary_expression) => walk_depth_first(ternary_expression, f),
BinaryExpression(binary_expression) => walk_depth_first(binary_expression, f),
PrefixExpression(prefix_expression) => walk_depth_first(prefix_expression, f),
SuffixExpression(suffix_expression) => walk_depth_first(suffix_expression, f),
CallExpression(call_expression) => walk_depth_first(call_expression, f),
TurboFish(turbo_fish) => walk_depth_first(turbo_fish, f),
CallArguments(call_arguments) => walk_depth_first(call_arguments, f),
CallArgument(call_argument) => walk_depth_first(call_argument, f),
Closure(closure) => walk_depth_first(closure, f),
ClosureCaptures(closure_captures) => walk_depth_first(closure_captures, f),
ClosureCapture(closure_capture) => walk_depth_first(closure_capture, f),
ClosureParameters(closure_parameters) => walk_depth_first(closure_parameters, f),
ClosureParameter(closure_parameter) => walk_depth_first(closure_parameter, f),
ObjectAccess(object_access) => walk_depth_first(object_access, f),
ObjectNavigations(object_navigations) => walk_depth_first(object_navigations, f),
ObjectNavigation(object_navigations) => walk_depth_first(object_navigations, f),
Literal(literal) => walk_depth_first(literal, f),
DString(d_string) => walk_depth_first(d_string, f),
DStringPart(d_string_part) => walk_depth_first(d_string_part, f),
}
}
f(node.as_node_ref());
}
// #[cfg(test)]
// mod tests {
// use crate::ast::build::build_ast;
// use crate::ast::children::NodeRef;
// use crate::ast::walk::walk_depth_first;
// use crate::parser::{DeimosParser, Rule};
// use indoc::indoc;
// use pest::Parser;
//
// #[test]
// fn collect_identifiers() {
// let parse_result = DeimosParser::parse(
// Rule::CompilationUnit,
// indoc! {"
// ns greeter;
//
// class Greeter {}
//
// fn main() {
// let greeter = Greeter();
// }
// "},
// );
// match parse_result {
// Ok(cu_pairs) => {
// let cu = build_ast("greeter.dm", 0, cu_pairs.into_iter().next().unwrap());
// let mut identifier_count = 0;
// walk_depth_first(&cu, &mut |node_ref| match node_ref {
// NodeRef::Identifier(identifier) => {
// dbg!(identifier);
// identifier_count += 1;
// }
// _ => {}
// });
// assert_eq!(identifier_count, 5);
// }
// Err(err) => {
// panic!("{}", err);
// }
// }
// }
// }