0

Visitor Pattern JavaScript

Ukeh Chisom 3 years ago 0
Here is a visitor pattern in JavaScript:

//ast.js

class BinaryOp{
  constructor(left, op, right){
    this.left = left;
    this.op = op;
    this.right = right;
    }
  
  accept(visitor){
    return visitor.visitBinaryOp(this);
    }
  }


class Literal{
  constructor(value){
    this.value = value;
    }
  
  accept(visitor){
    return visitor.visitLiteral(this);
    }
  }


//______________________________________________

//evaluator.js

/*
let tokens = new Tokenizer().tokenize(`
34 + 5 * 9
37 - 15
`);

const astFromParser = new Parser().parse(tokens)
*/

//an abstract syntax tree generated by the parser
const astFromParser = [
  new BinaryOp(
    new Literal(34),
    "ADD", //+
    new BinaryOp(new Literal(5),
       "MUL", //*
       new Literal(9)
      )
    ),
  
  new BinaryOp(new Literal(37),
    "SUB",//-
    new Literal(15)
    )
  ];


//the Visitor class is inmplemented as the Evaluator
class Evaluator{
  evaluateExpr(ast){
    try{
      for(let expr of ast){
        console.log(this.evaluate(expr));
        }
      }catch (err){
        alert(err);
        }
    }
  
  evaluate(ast){
    return ast.accept(this);
    }
  
  visitBinaryOp(init){
    switch(init.op){
      case "ADD":
        return this.evaluate(init.left) + this.evaluate(init.right);
      
      case "SUB":
        return this.evaluate(init.left) - this.evaluate(init.right);
      
      case "DIV":
        return this.evaluate(init.left) / this.evaluate(init.right);
     
      case "MUL":
        return this.evaluate(init.left) * this.evaluate(init.right);
      }
    }
  
  visitLiteral(init){
    return init.value;
    }
  }

var t = new Evaluator().evaluateExpr(astFromParser);
//output:
//79
//22

the operation of class BinaryOp() and Literal() are separated from their base classes and put in the Evaluator() class which act as the Visitor() class in this code 

those classes later access their operation from the Visitor class(Evaluator) using an accept method that keeps a parameter slot for the Visitor class granting the two base classes (BinaryOp and Literal) to the visitor methods were the BinaryOp calls the visitBinaryOp method of the visitor while Literal calls the visitLiteral method.