Interpreter

Interpreter pattern simply means converting a "language" into the system understandable execution sequences. In another words, you're interpreting from 1 set of grammar into another. Usually, interpreter has its own set of "language maps" that perform both language's mapping into one another. Here is a diagram:

When to Use (Problem)

  • When the problem requires one to define a translatable language (e.g. a scripting language for a heavily compiled program)
  • When the data transfer channel does not permits the normal standard structure (e.g. Base64 bytes transformation for ASCII-only channels)

Example (Solution)

Here is a solution in Go:

package main

import (
        "fmt"
        "strings"
)

const (
        Plus  = uint(0)
        Minus = uint(1)
)

func calculate(operation uint, a int, b int) {
        switch operation {
        case Plus:
                fmt.Printf("Total: %v + %v = %v\n", a, b, a+b)
        case Minus:
                fmt.Printf("Total: %v - %v = %v\n", a, b, a-b)
        }
}

type Interpreter struct {
}

func (i *Interpreter) Interpret(statement string) {
        words := strings.Split(statement, " ")

        a := -1
        b := -1
        op := uint(0)

        numbers := map[string]int{
                "zero":  0,
                "one":   1,
                "two":   2,
                "three": 3,
                "four":  4,
                "five":  5,
                "six":   6,
                "seven": 7,
                "eight": 8,
                "nine":  9,
        }

        for _, word := range words {
                w := strings.ToLower(word)
                x, ok := numbers[w]
                if ok {
                        if a == -1 {
                                a = x
                        } else if b == -1 {
                                b = x
                        }
                }

                switch w {
                case "plus":
                        op = Plus
                case "minus":
                        op = Minus
                }
        }

        calculate(op, a, b)
}

func main() {
        i := &Interpreter{}
        i.Interpret("One minus One")
        i.Interpret("One plus two")
        i.Interpret("One minus nine")
}

// Output:
// Total: 1 - 1 = 0
// Total: 1 + 2 = 3
// Total: 1 - 9 = -8

From the example above, notice that it is a simple calculator that translate English statement into mathematical calculation. It has 2 stages:

  • Interpreter that translate the English words into mathematical expression machine can understand.
  • Calculator that calculates and output the results

Notice that the Interpreter has 2 ways of translating the statements:

  • via word mapping
  • via switch cases

Expected Outcome (Consequences)

  • Application is able to interpret operations in a different grammar/"language".