# Introduction

In a previous article, I implemented parsing (http://qiita.com/quwahara/items/9bf468ff4286b28d2a24). By the way, I would like to use it to implement a simple interpreter.

# What you want to do with the interpreter

Confirm what you want to do in implementation. What we want to do with the interpreter is to calculate the programmed strings. Considering the following formula as an example, we aim to finally have `23` assigned to ʻa`.

``````a = 3 + 4 * 5
``````

# How to calculate

Now let's think about how to calculate. I parsed the expression in previous article. The parsed expression was parsed so that the operator tokens `left` and` right` have values calculated by that operator. For example, in the expression `6-7`, the operator token is` -`, `left` has` 6`, `right` has` 7`, and so on. Also, `left` and` right` may have not only values but also formulas that come first in the calculation order. For example, the expression `3 + 4 * 5` has the operator token`+`,` left` has `3`, and` right` has `4 * 5`. Since it has such a data structure, in order to calculate, go down the operator tokens `left` and` right` in order. When you reach the terminal operator, calculate it. Based on the calculation result, the operator one level higher is calculated. Calculation can be performed by repeating this operation up to the top. In the formula `3 + 4 * 5` in the previous example, the terminal operator is`*`of` 4 * 5`, so it is calculated to be `20`. The calculation result is used to calculate the operator `+` one level above. Since `left` is` 3` and `right` is the calculation result` 20`, it is added to `23` and the calculation is completed.

# Try to implement in Java

Move on to implementation. Let's take a look at the implementation of the interpreter.

First is the initialization part. Receives a list of tokens parsed by parsing. Calculate this token list. Also, since the interpreter corresponds to a variable, prepare a Map that holds the variable name and its value.

#### `Interpreter.java`

``````
public class Interpreter {

public Map<String, Integer> variables;
List<Token> body;

public Interpreter init(List<Token> body) {
variables = new HashMap<>();
this.body = body;
return this;
}
``````

This is a description of the part that starts the calculation. `run ()` calculates the token list` body` passed earlier and returns a variable Map that holds the calculation result.

#### `Interpreter.java`

``````
public Map<String, Integer> run() throws Exception {
body(body);
return variables;
}
``````

It is the explanation of the part to be calculated. `body ()` takes the token for one expression from the token list` body` passed earlier and passes it to ʻexpression ()` that processes the expression.

#### `Interpreter.java`

``````
public void body(List<Token> body) throws Exception {
for (Token exprs : body) {
expression(exprs);
}
}
``````

ʻExpression ()` calls the methods that process each token, depending on the meaning of the token, and returns the result as is.

#### `Interpreter.java`

``````
public Object expression(Token expr) throws Exception {
if (expr.kind.equals("digit")) {
return digit(expr);
} else if (expr.kind.equals("variable")) {
return var(expr);
} else if (expr.kind.equals("sign") && expr.value.equals("=")) {
return assign(expr);
} else if (expr.kind.equals("sign")) {
return calc(expr);
} else {
throw new Exception("Expression error");
}
}
``````

`digit ()` takes a numeric token and makes it ʻInteger`.

#### `Interpreter.java`

``````
public Integer digit(Token token) {
return Integer.decode(token.value);
}
``````

`var ()` takes the token of the variable and makes it the variable name. If the variable name is not registered in the variable Map, register the value with `0`.

#### `Interpreter.java`

``````
public Object var(Token token) {
String name = token.value;
if (!variables.containsKey(name)) {
variables.put(name, 0);
}
return name;
}
``````

ʻAssign ()` assigns a value to a variable.

#### `Interpreter.java`

``````
public String assign(Token expr) throws Exception {
String name = variable(expression(expr.left));
Integer value = value(expression(expr.right));
variables.put(name, value);
return name;
}
``````

`variable ()` is the process of ʻassign ()` and makes sure that the result of ʻexpr.left` is the variable name.

#### `Interpreter.java`

``````
public String variable(Object value) throws Exception {
if (value instanceof String) {
return (String) value;
} else {
throw new Exception("left value error");
}
}
``````

`value ()` is tailored to a numerical value that can be calculated by ʻexpr.right` in the processing of ʻassign ()` and the processing of the four arithmetic operations described later. If the argument `value` is ʻInteger`, it is returned as is. If it is `String`, the value is fetched from the variable Map and returned.

#### `Interpreter.java`

``````
public Integer value(Object value) throws Exception {
if (value instanceof Integer) {
return (Integer) value;
} else if (value instanceof String) {
return variables.get((String) value);
} else {
throw new Exception("right value error");
}
}
``````

`calc ()` performs four arithmetic operations.

#### `Interpreter.java`

``````
public Object calc(Token expr) throws Exception {
Integer left = value(expression(expr.left));
Integer right = value(expression(expr.right));
if (expr.value.equals("+")) {
return left + right;
} else if (expr.value.equals("-")) {
return left - right;
} else if (expr.value.equals("*")) {
return left * right;
} else if (expr.value.equals("/")) {
return left / right;
} else {
throw new Exception("Unknown sign for Calc");
}
}
``````

Using the above implementation, the string that is the example program

``````a = 3 + 4 * 5
``````

And print the variable and its value to standard output.

#### `Interpreter.java`

``````
public static void main(String[] args) throws Exception {
String text = "a = 3 + 4 * 5";
List<Token> tokens = new Lexer().init(text).tokenize();
List<Token> blk = new Parser().init(tokens).block();
Map<String, Integer> variables = new Interpreter().init(blk).run();
for (Map.Entry<String, Integer> variable : variables.entrySet()) {
System.out.println(variable.getKey() + " " + variable.getValue());
}
// --> a 23
}
}
``````

That's all for the implementation. Thank you very much.

# in conclusion

The source is available here.

Calc https://github.com/quwahara/Calc/tree/article-3-interpreter/Calc/src/main/java

There is a continuation article.

** Add println to the interpreter ** http://qiita.com/quwahara/items/82067b00cbe1cb974e4a

Finally, I will give you a summary of the Interpreter classes.

#### `Interpreter.java`

``````
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Interpreter {

public Map<String, Integer> variables;
List<Token> body;

public Interpreter init(List<Token> body) {
variables = new HashMap<>();
this.body = body;
return this;
}

public Map<String, Integer> run() throws Exception {
body(body);
return variables;
}

public void body(List<Token> body) throws Exception {
for (Token exprs : body) {
expression(exprs);
}
}

public Object expression(Token expr) throws Exception {
if (expr.kind.equals("digit")) {
return digit(expr);
} else if (expr.kind.equals("variable")) {
return var(expr);
} else if (expr.kind.equals("sign") && expr.value.equals("=")) {
return assign(expr);
} else if (expr.kind.equals("sign")) {
return calc(expr);
} else {
throw new Exception("Expression error");
}
}

public Integer digit(Token token) {
return Integer.decode(token.value);
}

public Object var(Token token) {
String name = token.value;
if (!variables.containsKey(name)) {
variables.put(name, 0);
}
return name;
}

public String assign(Token expr) throws Exception {
String name = variable(expression(expr.left));
Integer value = value(expression(expr.right));
variables.put(name, value);
return name;
}

public String variable(Object value) throws Exception {
if (value instanceof String) {
return (String) value;
} else {
throw new Exception("left value error");
}
}

public Integer value(Object value) throws Exception {
if (value instanceof Integer) {
return (Integer) value;
} else if (value instanceof String) {
return variables.get((String) value);
} else {
throw new Exception("right value error");
}
}

public Object calc(Token expr) throws Exception {
Integer left = value(expression(expr.left));
Integer right = value(expression(expr.right));
if (expr.value.equals("+")) {
return left + right;
} else if (expr.value.equals("-")) {
return left - right;
} else if (expr.value.equals("*")) {
return left * right;
} else if (expr.value.equals("/")) {
return left / right;
} else {
throw new Exception("Unknown sign for Calc");
}
}

public static void main(String[] args) throws Exception {
String text = "a = 3 + 4 * 5";
List<Token> tokens = new Lexer().init(text).tokenize();
List<Token> blk = new Parser().init(tokens).block();
Map<String, Integer> variables = new Interpreter().init(blk).run();
for (Map.Entry<String, Integer> variable : variables.entrySet()) {
System.out.println(variable.getKey() + " " + variable.getValue());
}
// --> a 23
}
}
``````