Clover coverage report - DynamicJava Test Coverage (dynamicjava-20130615-r5436)
Coverage timestamp: Sat Jun 15 2013 03:01:32 CDT
file stats: LOC: 86   Methods: 7
NCLOC: 61   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Interpreter.java 0% 81.5% 85.7% 77.8%
coverage coverage
 1    package edu.rice.cs.dynamicjava.interpreter;
 2   
 3    import java.io.StringReader;
 4    import edu.rice.cs.plt.tuple.Option;
 5    import edu.rice.cs.plt.tuple.Pair;
 6    import edu.rice.cs.plt.lambda.WrappedException;
 7   
 8    import koala.dynamicjava.tree.Node;
 9    import koala.dynamicjava.interpreter.error.ExecutionError;
 10    import koala.dynamicjava.parser.wrapper.JavaCCParser;
 11    import koala.dynamicjava.parser.wrapper.ParseError;
 12    import edu.rice.cs.dynamicjava.Options;
 13   
 14    import static edu.rice.cs.plt.debug.DebugUtil.debug;
 15   
 16    /**
 17    * The external interface for the interpreter.
 18    */
 19    public class Interpreter {
 20   
 21    private final Options _opt;
 22    private TypeContext _typeContext;
 23    private RuntimeBindings _bindings;
 24   
 25  183 public Interpreter(Options opt, TypeContext typeContext, RuntimeBindings bindings) {
 26  183 _opt = opt;
 27  183 _typeContext = typeContext;
 28  183 _bindings = bindings;
 29    // Force potentially expensive objects/classes to initialize now:
 30  183 _opt.typeSystem();
 31  183 new JavaCCParser(new StringReader(""), _opt).parseStream();
 32    }
 33   
 34  0 public Interpreter(Options opt) {
 35  0 this(opt, new ImportContext(Interpreter.class.getClassLoader(), opt), RuntimeBindings.EMPTY);
 36    }
 37   
 38  183 public Interpreter(Options opt, ClassLoader loader) {
 39  183 this(opt, new ImportContext(loader, opt), RuntimeBindings.EMPTY);
 40    }
 41   
 42  549 public Option<Object> interpret(String code) throws InterpreterException {
 43  549 Iterable<Node> tree = parse(code);
 44  549 debug.logValue("Parse result", tree);
 45  549 TypeContext tcResult = typeCheck(tree);
 46  502 debug.log("Static phase successful");
 47  502 Pair<RuntimeBindings, Option<Object>> evalResult = evaluate(tree);
 48    // We don't commit an environment change until evaluation has completed successfully. This
 49    // helps to guarantee that _typeContext and _bindings are in sync. Effects:
 50    // - If there's a static error in the entire tree, nothing runs.
 51    // - If evaluation halts halfway in, nothing (either previous or subsequent) gets defined.
 52    // - If evaluation halts halfway in, previous side effects (including mutation) *do* occur.
 53    // The alternative is to interpret the list of nodes incrementally, committing each change
 54    // before proceeding to the next. In this case, static errors later in the tree would not
 55    // prevent execution of earlier code.
 56  502 _typeContext = tcResult;
 57  502 _bindings = evalResult.first();
 58  502 return evalResult.second();
 59    }
 60   
 61  549 private Iterable<Node> parse(String code) throws InterpreterException {
 62  549 try {
 63  549 return new JavaCCParser(new StringReader(code), _opt).parseStream();
 64    }
 65    catch (ParseError e) {
 66  0 throw new ParserException(e);
 67    }
 68    }
 69   
 70  549 private TypeContext typeCheck(Iterable<Node> tree) throws InterpreterException {
 71  549 try { return new StatementChecker(_typeContext, _opt).checkList(tree); }
 72  47 catch (ExecutionError e) { throw new CheckerException(e); }
 73    }
 74   
 75  502 private Pair<RuntimeBindings, Option<Object>> evaluate(Iterable<Node> tree) throws InterpreterException {
 76  502 try {
 77  502 StatementEvaluator.Result r = new StatementEvaluator(_bindings, _opt).evaluateSequence(tree);
 78  502 return Pair.make(r.bindings(), r.value());
 79    }
 80    catch (WrappedException e) {
 81  0 if (e.getCause() instanceof InterpreterException) { throw (InterpreterException) e.getCause(); }
 82  0 else { throw e; }
 83    }
 84    }
 85   
 86    }