Infrastructure for separate-object block handler
Requires one unstable feature
This commit is contained in:
parent
8d3bbd7069
commit
b23b8ebdc7
@ -5,8 +5,10 @@ use crate::ast::*;
|
||||
//or a tuple of (T, <that type>)
|
||||
|
||||
pub trait ASTVisitor: Sized {
|
||||
type BlockHandler: BlockVisitor = ();
|
||||
fn ast(&mut self, _ast: &AST) {}
|
||||
fn block(&mut self, _statements: &Vec<Statement>) {}
|
||||
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() -> () { () }
|
||||
}
|
||||
|
||||
|
||||
|
@ -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: ASTVisitor>(v: &mut V, ast: &AST) {
|
||||
@ -10,10 +10,14 @@ pub fn walk_ast<V: ASTVisitor>(v: &mut V, ast: &AST) {
|
||||
}
|
||||
|
||||
fn walk_block<V: ASTVisitor>(v: &mut V, block: &Vec<Statement>) {
|
||||
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: ASTVisitor>(v: &mut V, statement: &Statement) {
|
||||
@ -44,7 +48,6 @@ fn declaration<V: ASTVisitor>(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: ASTVisitor>(v: &mut V, params: &Vec<FormalParam>, 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: ASTVisitor>(v: &mut V, arm: &ConditionArm) {
|
||||
v.expression(guard);
|
||||
expression(v, guard);
|
||||
});
|
||||
v.block(&arm.body);
|
||||
walk_block(v, &arm.body);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user