From b23b8ebdc71d1e1092e90bb1c3eff46b0436e61d Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 15 Dec 2019 11:56:49 -0800 Subject: [PATCH] Infrastructure for separate-object block handler Requires one unstable feature --- schala-lang/language/src/ast/visitor.rs | 16 +++++++++++++++- schala-lang/language/src/ast/walker.rs | 9 +++++---- schala-lang/language/src/lib.rs | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/schala-lang/language/src/ast/visitor.rs b/schala-lang/language/src/ast/visitor.rs index 05fc157..abd3ad7 100644 --- a/schala-lang/language/src/ast/visitor.rs +++ b/schala-lang/language/src/ast/visitor.rs @@ -5,8 +5,10 @@ use crate::ast::*; //or a tuple of (T, ) pub trait ASTVisitor: Sized { + type BlockHandler: BlockVisitor = (); fn ast(&mut self, _ast: &AST) {} - fn block(&mut self, _statements: &Vec) {} + fn block(&mut self) -> Self::BlockHandler { Self::BlockHandler::new() } + fn block_finished(&mut self, handler: Self::BlockHandler) {} fn statement(&mut self, _statement: &Statement) {} fn declaration(&mut self, _declaration: &Declaration) {} fn signature(&mut self, _signature: &Signature) {} @@ -39,3 +41,15 @@ pub trait ASTVisitor: Sized { fn prefix_exp(&mut self, _op: &PrefixOp, _arg: &Expression) {} fn pattern(&mut self, _pat: &Pattern) {} } + +pub trait BlockVisitor { + fn new() -> Self; + fn pre_block(&mut self) {} + fn post_block(&mut self) {} +} + +impl BlockVisitor for () { + fn new() -> () { () } +} + + diff --git a/schala-lang/language/src/ast/walker.rs b/schala-lang/language/src/ast/walker.rs index 1125b38..f59ca66 100644 --- a/schala-lang/language/src/ast/walker.rs +++ b/schala-lang/language/src/ast/walker.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] use std::rc::Rc; use crate::ast::*; -use crate::ast::visitor::ASTVisitor; +use crate::ast::visitor::{ASTVisitor, BlockVisitor}; use crate::util::deref_optional_box; pub fn walk_ast(v: &mut V, ast: &AST) { @@ -10,10 +10,14 @@ pub fn walk_ast(v: &mut V, ast: &AST) { } fn walk_block(v: &mut V, block: &Vec) { + let mut block_handler = v.block(); + block_handler.pre_block(); for s in block { v.statement(s); statement(v, s); } + block_handler.post_block(); + v.block_finished(block_handler); } fn statement(v: &mut V, statement: &Statement) { @@ -44,7 +48,6 @@ fn declaration(v: &mut V, decl: &Declaration) { }, FuncDecl(sig, block) => { v.signature(&sig); - v.block(&block); walk_block(v, block); }, TypeDecl { name, body, mutable } => v.type_declaration(name, body, *mutable), @@ -123,7 +126,6 @@ fn lambda(v: &mut V, params: &Vec, type_anno: Option formal_param(v, param); } v.type_annotation(type_anno); - v.block(body); walk_block(v, body); } @@ -234,7 +236,6 @@ fn condition_arm(v: &mut V, arm: &ConditionArm) { v.expression(guard); expression(v, guard); }); - v.block(&arm.body); walk_block(v, &arm.body); } diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index dfc32de..ff82209 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -1,5 +1,5 @@ +#![feature(associated_type_defaults)] //needed for Visitor trait #![feature(trace_macros)] -//#![feature(unrestricted_attribute_tokens)] #![feature(slice_patterns, box_patterns, box_syntax)] //! `schala-lang` is where the Schala programming language is actually implemented.