diff --git a/schala-lang/language/src/visitor.rs b/schala-lang/language/src/visitor.rs index ddda82a..c98a4d1 100644 --- a/schala-lang/language/src/visitor.rs +++ b/schala-lang/language/src/visitor.rs @@ -1,5 +1,6 @@ use std::error::Error; use crate::ast::*; +use crate::builtin::{PrefixOp, BinOp}; pub type VResult = Result<(), Box>; @@ -7,6 +8,9 @@ pub trait ASTVisitor { fn post_ast(&mut self, _: &mut AST) -> VResult { Ok(()) } + fn post_statement(&mut self, _: &mut Statement) -> VResult { + Ok(()) + } fn post_expression(&mut self, _: &mut Expression) -> VResult { Ok(()) } @@ -16,6 +20,12 @@ pub trait Visitable { fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult; } +impl Visitable for &mut T { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + self.visit(v) + } +} + impl Visitable for Option { fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { match self { @@ -25,10 +35,31 @@ impl Visitable for Option { } } +impl Visitable for Vec { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + for item in self { + item.visit(v)?; + } + Ok(()) + } +} + +impl Visitable for Box { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + self.visit(v) + } +} + +impl Visitable for Meta { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + self.node_mut().visit(v) + } +} + impl Visitable for AST { fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { for s in self.0.iter_mut() { - s.node_mut().visit(v)? + s.visit(v)? } v.post_ast(self) } @@ -37,20 +68,12 @@ impl Visitable for AST { impl Visitable for Statement { fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { match self { - Statement::ExpressionStatement(meta) => meta.node_mut().visit(v), + Statement::ExpressionStatement(meta) => meta.visit(v), Statement::Declaration(decl) => decl.visit(v), } } } -impl Visitable for Expression { - fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { - let _ = self.kind.visit(v)?; - let _ = self.type_anno.visit(v)?; - v.post_expression(self) - } -} - impl Visitable for Declaration { fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult { use Declaration::*; @@ -66,8 +89,93 @@ impl Visitable for Declaration { } } +impl Visitable for Expression { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + let _ = self.kind.visit(v)?; + let _ = self.type_anno.visit(v)?; + v.post_expression(self) + } +} + impl Visitable for ExpressionKind { - fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + use ExpressionKind::*; + Ok(match self { + NatLiteral(_) | FloatLiteral(_) | StringLiteral(_) + | BoolLiteral(_) => (), + BinExp(op, lhs, rhs) => { + let _ = op.visit(v)?; + let _ = lhs.visit(v)?; + let _ = rhs.visit(v)?; + () + }, + PrefixExp(op, expr) => { + let _ = op.visit(v)?; + let _ = expr.visit(v)?; + () + }, + TupleLiteral(exprs) => exprs.visit(v)?, + Value(_) => (), + NamedStruct { fields, .. } => { + let mut x: Vec<_> = fields.iter_mut().map(|(_, expr)| expr).collect(); + x.visit(v)? + }, + Call { f, arguments } => { + let _ = f.visit(v)?; + arguments.visit(v)? + }, + Index { indexee, indexers } => { + let _ = indexee.visit(v)?; + indexers.visit(v)? + }, + IfExpression { discriminator, body } => { + let _ = discriminator.visit(v)?; + body.visit(v)? + }, + WhileExpression { condition, body } => { + let _ = condition.visit(v)?; + body.visit(v)? + }, + ForExpression { enumerators, body } => { + let _ = enumerators.visit(v)?; + body.visit(v)? + }, + ListLiteral(expressions) => expressions.visit(v)?, + Lambda { params, type_anno, body } => { + let _ = params.visit(v)?; + let _ = type_anno.visit(v)?; + body.visit(v)? + }, + }) + } +} + +impl Visitable for IfExpressionBody { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +} + +impl Visitable for Discriminator { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +} + +impl Visitable for InvocationArgument { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +} + +impl Visitable for BinOp { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +} + +impl Visitable for PrefixOp { + fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult { Ok(()) } } @@ -77,3 +185,21 @@ impl Visitable for TypeIdentifier { Ok(()) } } + +impl Visitable for Enumerator { + fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +} + +impl Visitable for ForBody { + fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +} + +impl Visitable for FormalParam { + fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult { + Ok(()) + } +}