///|
pub fn visit_design(design : Design, visit : (String) -> Unit) -> Unit {
for mod in design.modules {
visit(mod.name)
for item in mod.items {
visit_item(item, visit)
}
}
}
///|
fn visit_item(item : ModuleItem, visit : (String) -> Unit) -> Unit {
match item {
Assign(assign) => {
visit_expression(assign.target, visit)
visit_expression(assign.value, visit)
}
Always(always) => visit_statement(always.body, visit)
Instance(instance) =>
for connection in instance.connections {
visit_expression(connection.expression, visit)
}
Statement(statement) => visit_statement(statement, visit)
Unknown(_) => ()
}
}
///|
fn visit_statement(statement : Statement, visit : (String) -> Unit) -> Unit {
match statement {
Empty(_) | Unknown(_) => ()
Block(statements, _) =>
for statement in statements {
visit_statement(statement, visit)
}
Assignment(target, value, _, _) => {
visit_expression(target, visit)
visit_expression(value, visit)
}
If(condition, then_branch, else_branch, _) => {
visit_expression(condition, visit)
visit_statement(then_branch, visit)
match else_branch {
Some(statement) => visit_statement(statement, visit)
None => ()
}
}
Case(expression, arms, _) => {
visit_expression(expression, visit)
for arm in arms {
for choice in arm.choices {
visit_expression(choice, visit)
}
visit_statement(arm.body, visit)
}
}
}
}
///|
fn visit_expression(expression : Expression, visit : (String) -> Unit) -> Unit {
match expression {
Name(name, _) => visit(name)
Number(_, _) | StringLiteral(_, _) | Unknown(_) => ()
Unary(_, inner, _) => visit_expression(inner, visit)
Binary(left, _, right, _) => {
visit_expression(left, visit)
visit_expression(right, visit)
}
Index(base, index, _) => {
visit_expression(base, visit)
visit_expression(index, visit)
}
}
}