Add a few more things to an Expression-only visitor

This commit is contained in:
greg 2019-07-30 00:32:25 -07:00
parent c3c515284d
commit 9d24d48825

View File

@ -1,33 +1,41 @@
use std::rc::Rc; use std::rc::Rc;
use crate::builtin::{BinOp, PrefixOp}; use crate::builtin::{BinOp, PrefixOp};
use crate::ast::{Expression, ExpressionKind}; use crate::ast::{Expression, ExpressionKind, InvocationArgument, Meta};
pub trait ExpressionKindVisitor<T> { pub trait ExpressionKindVisitor<T> {
fn nat_literal(&mut self, n: &u64) -> T; fn nat_literal(&mut self, n: &u64) -> T;
fn float_literal(&mut self, f: &f64) -> T;
fn string_literal(&mut self, s: Rc<String>) -> T; fn string_literal(&mut self, s: Rc<String>) -> T;
fn bool_literal(&mut self, b: &bool) -> T;
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> T; fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> T;
fn prefix_exp(&mut self, op: &PrefixOp, arg: &Expression) -> T;
fn value(&mut self, value_name: Rc<String>) -> T;
fn call_expression(&mut self, f: &Expression, arguments: &Vec<Meta<InvocationArgument>>) -> T;
} }
pub fn dispatch<T>(input: &ExpressionKind, visitor: &mut dyn ExpressionKindVisitor<T>) -> T { pub fn dispatch<T>(input: &ExpressionKind, visitor: &mut dyn ExpressionKindVisitor<T>) -> T {
use ExpressionKind::*; use ExpressionKind::*;
match input { match input {
NatLiteral(n) => visitor.nat_literal(n), NatLiteral(n) => visitor.nat_literal(n),
FloatLiteral(f) => visitor.float_literal(f),
StringLiteral(s) => visitor.string_literal(s.clone()), StringLiteral(s) => visitor.string_literal(s.clone()),
BoolLiteral(b) => visitor.bool_literal(b),
BinExp(op, box lhs, box rhs) => visitor.binexp(op, lhs.node(), rhs.node()), BinExp(op, box lhs, box rhs) => visitor.binexp(op, lhs.node(), rhs.node()),
PrefixExp(op, box arg) => visitor.prefix_exp(op, arg.node()),
Value(val_name) => visitor.value(val_name.clone()),
Call { box f, arguments } => visitor.call_expression(f.node(), arguments),
_ => panic!() _ => panic!()
} }
} }
/*
struct NumberSummer; struct NumberSummer;
impl ExpressionKindVisitor<u64> for NumberSummer { impl ExpressionKindVisitor<u64> for NumberSummer {
fn nat_literal(&mut self, n: &u64) -> u64 { fn nat_literal(&mut self, n: &u64) -> u64 { n.clone() }
n.clone() fn float_literal(&mut self, f: &f64) -> u64
} fn string_literal(&mut self, s: Rc<String>) -> u64 { 0 }
fn string_literal(&mut self, s: Rc<String>) -> u64 {
0
}
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> u64 { fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> u64 {
let lhs = dispatch(&lhs.kind, self); let lhs = dispatch(&lhs.kind, self);
let rhs = dispatch(&rhs.kind, self); let rhs = dispatch(&rhs.kind, self);
@ -46,3 +54,4 @@ fn yolo_swagg() {
let result = dispatch(&x, &mut t); let result = dispatch(&x, &mut t);
assert_eq!(result, 4); assert_eq!(result, 4);
} }
*/