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 ast(&mut self, ast: &AST) { } fn block(&mut self, statements: &Vec) {} fn statement(&mut self, statement: &Statement) {} fn declaration(&mut self, declaration: &Declaration) { } fn signature(&mut self, signature: &Signature) { } fn type_declaration(&mut self, name: &TypeSingletonName, body: &TypeBody, mutable: bool) { } fn type_alias(&mut self, old_name: &Rc, new_name: &Rc) { } fn binding(&mut self, name: &Rc, constant: bool, type_anno: Option<&TypeIdentifier>, expr: &Expression) { } fn implemention(&mut self, type_name: &TypeIdentifier, interface_name: Option<&TypeSingletonName>, block: &Vec) { } fn interface(&mut self, name: &Rc, signatures: &Vec) { } fn expression(&mut self, expression: &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)>) { walker::named_struct(self, name, fields); } fn call(&mut self, f: &Expression, arguments: &Vec) { walker::call(self, f, arguments); } fn index(&mut self, indexee: &Expression, indexers: &Vec) { walker::index(self, indexee, indexers); } fn if_expression(&mut self, discrim: &Discriminator, body: &IfExpressionBody) { } fn while_expression(&mut self, condition: Option<&Expression>, body: &Block) { } fn for_expression(&mut self, enumerators: &Vec, body: &ForBody) { } fn lambda(&mut self, params: &Vec, type_anno: Option<&TypeIdentifier>, body: &Block) { walker::lambda(self, params, type_anno, body); } fn invocation_argument(&mut self, arg: &InvocationArgument) { } fn formal_param(&mut self, param: &FormalParam) { walker::formal_param(self, param); } fn type_anno(&mut self, anno: &TypeIdentifier) { } 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); } }