Skip to content

Commit

Permalink
refactor: Separate declartion & body visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
sbwtw committed Dec 12, 2023
1 parent 12f5641 commit 5ab71fd
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 172 deletions.
4 changes: 4 additions & 0 deletions lib/src/ast/declaration_statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const EMPTY_VARIABLES: &[Rc<Variable>] = &[];
#[derive(Debug)]
pub enum DeclKind {
Fun(Box<FunctionDeclare>),
Prg(Box<FunctionDeclare>),
FB(Box<FunctionDeclare>),
Alias(Box<AliasDeclare>),
Struct(Box<StructDeclare>),
Enum(Box<EnumDeclare>),
Expand All @@ -21,6 +23,8 @@ impl Declaration {
pub fn identifier(&self) -> &StString {
match self.kind {
DeclKind::Fun(ref fun) => fun.name(),
DeclKind::FB(ref fun) => fun.name(),
DeclKind::Prg(ref fun) => fun.name(),
DeclKind::Alias(ref alias) => alias.name(),
DeclKind::Struct(ref struct_) => struct_.name(),
DeclKind::Enum(ref enum_) => enum_.name(),
Expand Down
3 changes: 1 addition & 2 deletions lib/src/ast/function_declaration.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::ast::{AstVisitor, DeclareClass, Type, Variable};
use crate::impl_ast_display;
use crate::parser::StString;
use crate::prelude::*;
use smallvec::SmallVec;
use std::rc::Rc;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod types;
pub use types::*;

mod visitor;
pub use visitor::{AstVisitor, AstVisitorMut};
pub use visitor::{AstVisitor, AstVisitorMut, DeclVisitor};

mod function_declaration;
pub use function_declaration::FunctionDeclare;
Expand Down
149 changes: 79 additions & 70 deletions lib/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@ use crate::ast::{
};

// Mutable visitor
pub trait DeclVisitorMut: Sized {
fn visit_declaration_mut(&mut self, decl: &mut Declaration) {
walk_declaration_mut(self, decl)
}

fn visit_function_declaration_mut(&mut self, decl: &mut FunctionDeclare) {
walk_function_declaration_mut(self, decl)
}

fn visit_enum_declaration_mut(&mut self, decl: &mut EnumDeclare) {
walk_enum_declaration_mut(self, decl)
}

fn visit_alias_declaration_mut(&mut self, decl: &mut AliasDeclare) {
walk_alias_declaration_mut(self, decl)
}

fn visit_struct_declaration_mut(&mut self, decl: &mut StructDeclare) {
walk_struct_declaration_mut(self, decl)
}

fn visit_global_variable_declaration_mut(&mut self, decl: &mut GlobalVariableDeclare) {
walk_global_variable_declaration_mut(self, decl)
}

fn visit_variable_declaration_mut(&mut self, variable: &mut Variable) {
walk_variable_declaration_mut(self, variable)
}
}

pub trait AstVisitorMut: Sized {
fn visit_literal_mut(&mut self, literal: &mut LiteralExpression) {
walk_literal_mut(self, literal)
Expand Down Expand Up @@ -42,34 +72,6 @@ pub trait AstVisitorMut: Sized {
walk_if_statement_mut(self, ifst)
}

fn visit_declaration_mut(&mut self, decl: &mut Declaration) {
walk_declaration_mut(self, decl)
}

fn visit_function_declaration_mut(&mut self, decl: &mut FunctionDeclare) {
walk_function_declaration_mut(self, decl)
}

fn visit_enum_declaration_mut(&mut self, decl: &mut EnumDeclare) {
walk_enum_declaration_mut(self, decl)
}

fn visit_alias_declaration_mut(&mut self, decl: &mut AliasDeclare) {
walk_alias_declaration_mut(self, decl)
}

fn visit_struct_declaration_mut(&mut self, decl: &mut StructDeclare) {
walk_struct_declaration_mut(self, decl)
}

fn visit_global_variable_declaration_mut(&mut self, decl: &mut GlobalVariableDeclare) {
walk_global_variable_declaration_mut(self, decl)
}

fn visit_variable_declaration_mut(&mut self, variable: &mut Variable) {
walk_variable_declaration_mut(self, variable)
}

fn visit_operator_expression_mut(&mut self, operator: &mut OperatorExpression) {
walk_operator_expression_mut(self, operator)
}
Expand Down Expand Up @@ -145,37 +147,39 @@ fn walk_if_statement_mut<V: AstVisitorMut>(vis: &mut V, ifst: &mut IfStatement)
}

#[inline]
fn walk_declaration_mut<V: AstVisitorMut>(vis: &mut V, decl: &mut Declaration) {
fn walk_declaration_mut<V: DeclVisitorMut>(vis: &mut V, decl: &mut Declaration) {
match decl.kind {
DeclKind::Struct(ref mut struct_) => vis.visit_struct_declaration_mut(struct_),
DeclKind::Enum(ref mut enum_) => vis.visit_enum_declaration_mut(enum_),
DeclKind::Alias(ref mut alias) => vis.visit_alias_declaration_mut(alias),
DeclKind::Fun(ref mut fun) => vis.visit_function_declaration_mut(fun),
DeclKind::FB(ref mut fun) => vis.visit_function_declaration_mut(fun),
DeclKind::Prg(ref mut fun) => vis.visit_function_declaration_mut(fun),
DeclKind::GlobalVar(ref mut gv) => vis.visit_global_variable_declaration_mut(gv),
}
}

#[inline]
fn walk_struct_declaration_mut<V: AstVisitorMut>(_: &mut V, _: &mut StructDeclare) {}
fn walk_struct_declaration_mut<V: DeclVisitorMut>(_: &mut V, _: &mut StructDeclare) {}

#[inline]
fn walk_global_variable_declaration_mut<V: AstVisitorMut>(
fn walk_global_variable_declaration_mut<V: DeclVisitorMut>(
_: &mut V,
_: &mut GlobalVariableDeclare,
) {
}

#[inline]
fn walk_enum_declaration_mut<V: AstVisitorMut>(_: &mut V, _: &mut EnumDeclare) {}
fn walk_enum_declaration_mut<V: DeclVisitorMut>(_: &mut V, _: &mut EnumDeclare) {}

#[inline]
fn walk_alias_declaration_mut<V: AstVisitorMut>(_: &mut V, _: &mut AliasDeclare) {}
fn walk_alias_declaration_mut<V: DeclVisitorMut>(_: &mut V, _: &mut AliasDeclare) {}

#[inline]
fn walk_function_declaration_mut<V: AstVisitorMut>(_: &mut V, _: &mut FunctionDeclare) {}
fn walk_function_declaration_mut<V: DeclVisitorMut>(_: &mut V, _: &mut FunctionDeclare) {}

#[inline]
fn walk_variable_declaration_mut<V: AstVisitorMut>(_: &mut V, _: &mut Variable) {}
fn walk_variable_declaration_mut<V: DeclVisitorMut>(_: &mut V, _: &mut Variable) {}

#[inline]
fn walk_operator_expression_mut<V: AstVisitorMut>(vis: &mut V, operator: &mut OperatorExpression) {
Expand All @@ -200,6 +204,37 @@ fn walk_compo_access_expression_mut<V: AstVisitorMut>(
}

// Immutable visitor

pub trait DeclVisitor<'ast>: Sized {
fn visit_declaration(&mut self, decl: &'ast Declaration) {
walk_declaration(self, decl)
}

fn visit_function_declaration(&mut self, decl: &'ast FunctionDeclare) {
walk_function_declaration(self, decl)
}

fn visit_enum_declaration(&mut self, decl: &'ast EnumDeclare) {
walk_enum_declaration(self, decl)
}

fn visit_alias_declaration(&mut self, decl: &'ast AliasDeclare) {
walk_alias_declaration(self, decl)
}

fn visit_struct_declaration(&mut self, decl: &'ast StructDeclare) {
walk_struct_declaration(self, decl)
}

fn visit_global_variable_declaration(&mut self, decl: &'ast GlobalVariableDeclare) {
walk_global_variable_declaration(self, decl)
}

fn visit_variable_declaration(&mut self, variable: &'ast Variable) {
walk_variable_declaration(self, variable)
}
}

pub trait AstVisitor<'ast>: Sized {
fn visit_literal(&mut self, literal: &'ast LiteralExpression) {
walk_literal(self, literal)
Expand Down Expand Up @@ -233,34 +268,6 @@ pub trait AstVisitor<'ast>: Sized {
walk_if_statement(self, ifst)
}

fn visit_declaration(&mut self, decl: &'ast Declaration) {
walk_declaration(self, decl)
}

fn visit_function_declaration(&mut self, decl: &'ast FunctionDeclare) {
walk_function_declaration(self, decl)
}

fn visit_enum_declaration(&mut self, decl: &'ast EnumDeclare) {
walk_enum_declaration(self, decl)
}

fn visit_alias_declaration(&mut self, decl: &'ast AliasDeclare) {
walk_alias_declaration(self, decl)
}

fn visit_struct_declaration(&mut self, decl: &'ast StructDeclare) {
walk_struct_declaration(self, decl)
}

fn visit_global_variable_declaration(&mut self, decl: &'ast GlobalVariableDeclare) {
walk_global_variable_declaration(self, decl)
}

fn visit_variable_declaration(&mut self, variable: &'ast Variable) {
walk_variable_declaration(self, variable)
}

fn visit_operator_expression(&mut self, operator: &'ast OperatorExpression) {
walk_operator_expression(self, operator)
}
Expand Down Expand Up @@ -336,37 +343,39 @@ fn walk_if_statement<'a, V: AstVisitor<'a>>(vis: &mut V, ifst: &'a IfStatement)
}

#[inline]
fn walk_declaration<'a, V: AstVisitor<'a>>(vis: &mut V, decl: &'a Declaration) {
fn walk_declaration<'a, V: DeclVisitor<'a>>(vis: &mut V, decl: &'a Declaration) {
match decl.kind {
DeclKind::Struct(ref struct_) => vis.visit_struct_declaration(struct_),
DeclKind::Enum(ref enum_) => vis.visit_enum_declaration(enum_),
DeclKind::Alias(ref alias) => vis.visit_alias_declaration(alias),
DeclKind::Fun(ref fun) => vis.visit_function_declaration(fun),
DeclKind::FB(ref fun) => vis.visit_function_declaration(fun),
DeclKind::Prg(ref fun) => vis.visit_function_declaration(fun),
DeclKind::GlobalVar(ref gv) => vis.visit_global_variable_declaration(gv),
}
}

#[inline]
fn walk_struct_declaration<'a, V: AstVisitor<'a>>(_: &mut V, _: &'a StructDeclare) {}
fn walk_struct_declaration<'a, V: DeclVisitor<'a>>(_: &mut V, _: &'a StructDeclare) {}

#[inline]
fn walk_enum_declaration<'a, V: AstVisitor<'a>>(_: &mut V, _: &'a EnumDeclare) {}
fn walk_enum_declaration<'a, V: DeclVisitor<'a>>(_: &mut V, _: &'a EnumDeclare) {}

#[inline]
fn walk_alias_declaration<'a, V: AstVisitor<'a>>(_: &mut V, _: &'a AliasDeclare) {}
fn walk_alias_declaration<'a, V: DeclVisitor<'a>>(_: &mut V, _: &'a AliasDeclare) {}

#[inline]
fn walk_function_declaration<'a, V: AstVisitor<'a>>(_: &mut V, _: &'a FunctionDeclare) {}
fn walk_function_declaration<'a, V: DeclVisitor<'a>>(_: &mut V, _: &'a FunctionDeclare) {}

#[inline]
fn walk_global_variable_declaration<'a, V: AstVisitor<'a>>(
fn walk_global_variable_declaration<'a, V: DeclVisitor<'a>>(
_: &mut V,
_: &'a GlobalVariableDeclare,
) {
}

#[inline]
fn walk_variable_declaration<'a, V: AstVisitor<'a>>(_: &mut V, _: &'a Variable) {}
fn walk_variable_declaration<'a, V: DeclVisitor<'a>>(_: &mut V, _: &'a Variable) {}

#[inline]
fn walk_operator_expression<'a, V: AstVisitor<'a>>(vis: &mut V, operator: &'a OperatorExpression) {
Expand Down
11 changes: 11 additions & 0 deletions lib/src/context/module_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ impl PrototypeImpl {
self.variables().iter().find(|x| x.name() == self.name())
}

/// return false if Prototype is Function, like FB or Fun or Prg
pub fn is_type_declaration(&self) -> bool {
matches!(
self.decl.kind,
Expand All @@ -154,6 +155,16 @@ fn proto_name_string(name: &StString) -> Cow<String> {
impl Display for PrototypeImpl {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match &self.decl.kind {
DeclKind::FB(fun) => f.write_fmt(format_args!(
"{} ({})",
proto_name_string(fun.name()),
"FUNCTION_BLOCK"
)),
DeclKind::Prg(fun) => f.write_fmt(format_args!(
"{} ({})",
proto_name_string(fun.name()),
"PROGRAM"
)),
DeclKind::Fun(fun) => f.write_fmt(format_args!(
"{} ({})",
proto_name_string(fun.name()),
Expand Down
1 change: 1 addition & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod utils;
pub mod prelude {
pub use crate::ast::*;
pub use crate::context::*;
pub use crate::parser::StString;
}

#[cfg(test)]
Expand Down
28 changes: 15 additions & 13 deletions lib/src/utils/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,21 @@ fn display_type(ty: Option<Rc<Box<dyn Type>>>) -> String {
ty.map(|x| x.to_string()).unwrap_or_default()
}

impl<W: Write> DeclVisitor<'_> for GraphvizExporter<W> {
fn visit_declaration(&mut self, decl: &Declaration) {
let name = self.unique_name("declaration_statement");

let mut buf = vec![];
let mut stringify = StringifyVisitor::new(&mut buf);
stringify.visit_declaration(decl);

let s = String::from_utf8_lossy(&buf);
let labels = GraphvizLabelGroup::from_name("Declaration")
.append_group(GraphvizLabelGroup::from_name(s));
self.write_node(&name, labels);
}
}

impl<W: Write> AstVisitor<'_> for GraphvizExporter<W> {
fn visit_literal(&mut self, literal: &LiteralExpression) {
let name = self.unique_name("literal");
Expand Down Expand Up @@ -369,19 +384,6 @@ impl<W: Write> AstVisitor<'_> for GraphvizExporter<W> {
}
}

fn visit_declaration(&mut self, decl: &Declaration) {
let name = self.unique_name("declaration_statement");

let mut buf = vec![];
let mut stringify = StringifyVisitor::new(&mut buf);
stringify.visit_declaration(decl);

let s = String::from_utf8_lossy(&buf);
let labels = GraphvizLabelGroup::from_name("Declaration")
.append_group(GraphvizLabelGroup::from_name(s));
self.write_node(&name, labels);
}

fn visit_operator_expression(&mut self, expr: &OperatorExpression) {
let name = self.unique_name("operator_expression");

Expand Down
12 changes: 7 additions & 5 deletions lib/src/utils/hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ impl Hasher for Crc32Hasher<'_> {
}
}

impl<H: Hasher> DeclVisitor<'_> for AstHasher<H> {
fn visit_declaration(&mut self, _: &Declaration) {
VisitType::DeclarationStatement.hash(&mut self.hasher);
unimplemented!()
}
}

impl<H: Hasher> AstVisitor<'_> for AstHasher<H> {
fn visit_literal(&mut self, literal: &LiteralExpression) {
VisitType::Literal.hash(&mut self.hasher);
Expand Down Expand Up @@ -151,11 +158,6 @@ impl<H: Hasher> AstVisitor<'_> for AstHasher<H> {
}
}

fn visit_declaration(&mut self, _: &Declaration) {
VisitType::DeclarationStatement.hash(&mut self.hasher);
unimplemented!()
}

fn visit_operator_expression(&mut self, op_expr: &OperatorExpression) {
VisitType::OperatorExpression.hash(&mut self.hasher);
op_expr.op().hash(&mut self.hasher);
Expand Down
Loading

0 comments on commit 5ab71fd

Please sign in to comment.