소스 검색

Add interpreter

pull/1/head
Malte Schmitz 9 년 전
부모
커밋
8bd057d745
7개의 변경된 파일218개의 추가작업 그리고 0개의 파일을 삭제
  1. +45
    -0
      src/interpreter/Evaluator.java
  2. +28
    -0
      src/interpreter/ExpressionVisitor.java
  3. +63
    -0
      src/interpreter/Interpreter.java
  4. +7
    -0
      src/interpreter/InterpreterException.java
  5. +18
    -0
      src/interpreter/ProgramVisitor.java
  6. +21
    -0
      test/interpreter/EvaluatorTest.java
  7. +36
    -0
      test/interpreter/InterpreterTest.java

+ 45
- 0
src/interpreter/Evaluator.java 파일 보기

@@ -0,0 +1,45 @@
package interpreter;

import expression.*;

import java.util.HashMap;
import java.util.Map;

public class Evaluator extends ExpressionVisitor<Integer> {

final Expression expression;
final Map<String, Integer> valuation = new HashMap<>();

public Evaluator(Expression expression, Map<String, Integer> valuation) {
this.expression = expression;
this.valuation.putAll(valuation);
}

public int eval() {
return visit(expression);
}

@Override
public Integer visitAddition(Addition addition) {
return visit(addition.leftHandSide) + visit(addition.rightHandSide);
}

@Override
public Integer visitSubtraction(Subtraction subtraction) {
return visit(subtraction.leftHandSide) - visit(subtraction.rightHandSide);
}

@Override
public Integer visitInt(Int integer) {
return integer.value;
}

@Override
public Integer visitIdentifier(Identifier identifier) {
if (valuation.containsKey(identifier.name)) {
return valuation.get(identifier.name);
} else {
throw new InterpreterException("Identifier " + identifier.name + " not found.");
}
}
}

+ 28
- 0
src/interpreter/ExpressionVisitor.java 파일 보기

@@ -0,0 +1,28 @@
package interpreter;

import expression.*;
import java.lang.reflect.Method;

public abstract class ExpressionVisitor<T> {
public T visit(Expression expression) {
String methodName = "visit" + expression.getClass().getSimpleName();
Method method;
try {
method = this.getClass().getMethod(methodName, expression.getClass());
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
Object result;
try {
result = method.invoke(this, expression);
} catch (Exception e) {
throw new RuntimeException(e);
}
return (T) result;
}

public abstract T visitAddition(Addition addition);
public abstract T visitSubtraction(Subtraction subtraction);
public abstract T visitInt(Int integer);
public abstract T visitIdentifier(Identifier identifier);
}

+ 63
- 0
src/interpreter/Interpreter.java 파일 보기

@@ -0,0 +1,63 @@
package interpreter;

import program.*;

import java.util.HashMap;
import java.util.Map;

public class Interpreter extends ProgramVisitor {
final Program program;
final Map<String, Integer> valuation = new HashMap<>();

public Map<String, Integer> getValuation() {
Map<String, Integer> result = new HashMap<>();
result.putAll(valuation);
return result;
}

public Interpreter(Program program) {
this.program = program;
visit(program);
}

public Interpreter(Program program, Map<String, Integer> valuation) {
this.program = program;
this.valuation.putAll(valuation);
visit(program);
}


@Override
public void visitAssignment(Assignment assignment) {
Evaluator evaluator = new Evaluator(assignment.expression, valuation);
valuation.put(assignment.identifier.name, evaluator.eval());
}

@Override
public void visitComposition(Composition composition) {
visit(composition.first);
visit(composition.second);
}

@Override
public void visitConditional(Conditional conditional) {
Evaluator evaluator = new Evaluator(conditional.condition, valuation);
if (evaluator.eval() != 0) {
visit(conditional.thenCase);
} else {
visit(conditional.elseCase);
}
}

private boolean enterLoop(Loop loop) {
Evaluator evaluator = new Evaluator(loop.condition, valuation);
return evaluator.eval() != 0;
}

@Override
public void visitLoop(Loop loop) {
while(enterLoop(loop)) {
visit(loop.program);
}
}
}

+ 7
- 0
src/interpreter/InterpreterException.java 파일 보기

@@ -0,0 +1,7 @@
package interpreter;

public class InterpreterException extends RuntimeException {
public InterpreterException(String error) {
super(error);
}
}

+ 18
- 0
src/interpreter/ProgramVisitor.java 파일 보기

@@ -0,0 +1,18 @@
package interpreter;

import program.*;

public abstract class ProgramVisitor {
public void visit(Program program) {
try {
this.getClass().getMethod("visit" + program.getClass().getSimpleName(), program.getClass()).invoke(this, program);
} catch(Exception ex) {
throw new RuntimeException(ex);
}
}

public abstract void visitAssignment(Assignment assignment);
public abstract void visitComposition(Composition composition);
public abstract void visitConditional(Conditional conditional);
public abstract void visitLoop(Loop loop);
}

+ 21
- 0
test/interpreter/EvaluatorTest.java 파일 보기

@@ -0,0 +1,21 @@
package interpreter;

import expression.*;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.assertEquals;

public class EvaluatorTest {
@Test
public void testEval() {
Map<String, Integer> valuation = new HashMap<>();
valuation.put("x", 7);
valuation.put("y", 2);
Expression expression = new Addition(new Identifier("x"), new Subtraction(new Identifier("y"), new Int(-4)));
Evaluator evaluator = new Evaluator(expression, valuation);
assertEquals(13, evaluator.eval());
}
}

+ 36
- 0
test/interpreter/InterpreterTest.java 파일 보기

@@ -0,0 +1,36 @@
package interpreter;

import expression.Addition;
import expression.Identifier;
import expression.Int;
import expression.Subtraction;
import org.junit.Test;
import program.Assignment;
import program.Composition;
import program.Loop;
import program.Program;

import java.util.Map;

import static org.junit.Assert.assertEquals;

public class InterpreterTest {
@Test
public void testSem() {
Program initialization = new Composition(
new Composition(
new Assignment(new Identifier("a"), new Int(2)),
new Assignment(new Identifier("b"), new Int(4))),
new Assignment(new Identifier("r"), new Int(0)));
Program body = new Composition(
new Assignment(new Identifier("r"), new Addition(new Identifier("r"), new Identifier("b"))),
new Assignment(new Identifier("a"), new Subtraction(new Identifier("a"), new Int(1))));
Program loop = new Loop(new Identifier("a"), body);
Program program = new Composition(initialization, loop);
Interpreter interpreter = new Interpreter(program);
Map<String, Integer> valuation = interpreter.getValuation();
assertEquals(8, valuation.get("r").intValue());
assertEquals(0, valuation.get("a").intValue());
assertEquals(4, valuation.get("b").intValue());
}
}

불러오는 중...
취소
저장