diff --git a/schala-lang/language/src/ast_visitor.rs b/schala-lang/language/src/ast_visitor.rs index 21dcdbe..fad2489 100644 --- a/schala-lang/language/src/ast_visitor.rs +++ b/schala-lang/language/src/ast_visitor.rs @@ -5,17 +5,17 @@ use ast::*; pub fn dispatch>(visitor: &mut V, ast: &AST) -> T { visitor.ast(ast); for statement in ast.0.iter() { - visitor.statement(statement); - match statement { + let output = match statement { Statement::ExpressionStatement(expr) => { let ref mut expression_visitor = visitor.expression(); - ExpressionVisitor::dispatch(expression_visitor, expr); + ExpressionVisitor::dispatch(expression_visitor, expr) }, Statement::Declaration(decl) => { let ref mut declaration_visitor = visitor.declaration(); - DeclarationVisitor::dispatch(declaration_visitor, decl); + DeclarationVisitor::dispatch(declaration_visitor, decl) }, - } + }; + visitor.statement(output); } visitor.done() } @@ -25,7 +25,7 @@ pub trait ASTVisitor { type DV : DeclarationVisitor; fn ast(&mut self, _ast: &AST) { } - fn statement(&mut self, _statement: &Statement) { } + fn statement(&mut self, T) { } fn expression(&mut self) -> Self::EV; fn declaration(&mut self) -> Self::DV; fn done(&mut self) -> T; @@ -48,9 +48,9 @@ pub trait DeclarationVisitor { FuncDecl(sig, block) => visitor.func_declaration(sig, block), TypeDecl { name, body, mutable } => visitor.type_declaration(name, body, mutable), TypeAlias(alias, name) => visitor.type_alias(alias, name), - Binding { .. } => unimplemented!(), - Impl { .. } => unimplemented!(), - Interface { .. } => unimplemented!(), + Binding { name, constant, expr} => visitor.binding(name, constant, expr), + Impl { type_name, interface_name, block } => visitor.impl_block(type_name, interface_name, block), + Interface { name, signatures } => visitor.interface(name, signatures), }; visitor.done() } @@ -60,42 +60,12 @@ pub trait DeclarationVisitor { fn func_declaration(&mut self, _sig: &Signature, _block: &Vec) { } fn type_declaration(&mut self, _name: &TypeSingletonName, _body: &TypeBody, _mutable: &bool) { } fn type_alias(&mut self, _alias: &Rc, _name: &Rc) { } + fn binding(&mut self, _name: &Rc, _constant: &bool, _expr: &Expression) { } + fn impl_block(&mut self, _type_name: &TypeIdentifier, _interface_name: &Option, _block: &Vec) { } + fn interface(&mut self, name: &Rc, signatures: &Vec) { } fn done(&mut self) -> T; } -/*----*/ - - -struct NullVisitor { } -impl ASTVisitor<()> for NullVisitor { - type EV = NullVisitor; - type DV = NullVisitor; - fn done(&mut self) -> () { - () - } - - fn expression(&mut self) -> Self::EV { - NullVisitor { } - } - - fn declaration(&mut self) -> Self::DV { - NullVisitor { } - } -} - -impl ExpressionVisitor<()> for NullVisitor { - fn done(&mut self) -> () { - () - } -} - -impl DeclarationVisitor<()> for NullVisitor { - fn done(&mut self) -> () { - () - } -} - - #[derive(Default, Clone)] struct SchalaPrinter { s: String @@ -108,6 +78,11 @@ impl ASTVisitor for SchalaPrinter { self.s.push_str("Pretty-printed AST"); } + fn statement(&mut self, s: String) { + self.s.push_str("\n"); + self.s.push_str(&s); + } + fn expression(&mut self) -> Self::EV { SchalaPrinter::default() } @@ -137,6 +112,7 @@ mod visitor_tests { use ::tokenizing::{Token, tokenize}; use ::parsing::ParseResult; use ::ast::AST; + use super::*; fn parse(input: &str) -> ParseResult { let tokens = tokenize(input); @@ -146,6 +122,14 @@ mod visitor_tests { #[test] fn test() { - let q = parse("foo"); + let ast = parse("let a = 1 + 2; let b = 2 + 44;foo()").unwrap(); + let mut pp = SchalaPrinter::default(); + + let result = dispatch(&mut pp, &ast); + assert_eq!(result, r#"Pretty-printed AST +let a = 1 + 2 +let b = 2 + 44 +foo() +"#); } }