Starting to experiment with a returning-style visitor

This commit is contained in:
greg 2019-11-11 01:57:27 -08:00
parent 8de625e540
commit 1bc684fa15
2 changed files with 42 additions and 0 deletions

View File

@ -39,3 +39,33 @@ pub trait ASTVisitor: Sized {
fn prefix_exp(&mut self, _op: &PrefixOp, _arg: &Expression) {}
fn pattern(&mut self, _pat: &Pattern) {}
}
pub trait ExpressionVisitor<T> {
fn type_anno(&mut self, _anno: &TypeIdentifier) -> T;
fn nat_literal(&mut self, _value: &u64) -> T;
fn string_literal(&mut self, _value: &Rc<String>) -> T;
fn binexp(&mut self, _op: &BinOp, _lhs: &Expression, _rhs: &Expression) -> T;
fn done(&mut self, kind: T, anno: Option<T>) -> T;
}
pub fn dispatch_expression_kind_visitor<T>(input: &AST, visitor: &mut dyn ExpressionVisitor<T>) -> Result<T, String> {
if input.statements.len() != 1 {
return Err(format!("One statement only!"));
}
let expr = match input.statements[0].kind {
StatementKind::Expression(ref expr) => expr,
_ => return Err(format!("Single statement needs to be an expr!")),
};
let output = match expr.kind {
ExpressionKind::NatLiteral(ref n) => visitor.nat_literal(n),
ExpressionKind::StringLiteral(ref s) => visitor.string_literal(s),
ExpressionKind::BinExp(ref op, ref lhs, ref rhs) => {
visitor.binexp(op, lhs, rhs)
},
_ => return Err(format!("Lol not done yet!")),
};
let type_output = expr.type_anno.as_ref().map(|anno| visitor.type_anno(anno));
Ok(visitor.done(output, type_output))
}

View File

@ -39,3 +39,15 @@ fn heh() {
assert_eq!(tester.count, 6);
assert_eq!(tester.float_count, 1);
}
struct NewTester {
}
#[test]
fn new_visitor() {
}