use std::rc::Rc; use std::error::Error; use crate::ast::*; use crate::ast::walker; //TODO maybe these functions should take closures that return a KeepRecursing | StopHere type, //or a tuple of (T, ) //TODO default implmentations should call walk methods - then I can test printing pub trait ASTVisitor: Sized { fn visit(&mut self, ast: &AST) { println!("FUCK"); walker::ast(self, ast); } fn block(&mut self, statements: &Vec) { println!("oi"); walker::block(self, statements); } fn statement(&mut self, statement: &Statement) { println!("stmt"); walker::statement(self, statement); } fn declaration(&mut self, declaration: &Declaration) { walker::declaration(self, declaration); } fn signature(&mut self, signature: &Signature) { } fn binding(&mut self, name: &Rc, constant: bool, type_anno: Option<&TypeIdentifier>, expr: &Expression) { walker::maybe_type_identifier(self, type_anno); walker::expression(self, expr); } fn expression(&mut self, expression: &Expression) { println!("expr yo"); walker::expression(self, expression); } fn expression_kind(&mut self, kind: &ExpressionKind) { walker::expression_kind(self, kind); } fn maybe_type_identifier(&mut self, type_anno: Option<&TypeIdentifier>) { walker::maybe_type_identifier(self, type_anno); } fn named_struct(&mut self, name: &QualifiedName, fields: &Vec<(Rc, Expression)>) { self.qualified_name(name); for (_, expr) in fields.iter() { walker::expression(self, expr); } } fn import(&mut self, import: &ImportSpecifier) {} fn qualified_name(&mut self, name: &QualifiedName) {} fn nat_literal(&mut self, n: u64) {} fn float_literal(&mut self, f: f64) {} fn string_literal(&mut self, s: &Rc) {} fn bool_literal(&mut self, b: bool) {} fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) { walker::expression(self, lhs); walker::expression(self, rhs); } fn prefix_exp(&mut self, op: &PrefixOp, arg: &Expression) { walker::expression(self, arg); } }