예제 #1
0
 private ExpResult eagerEval(EvalContext ec) throws ExpError {
   ExpResult condRes = constCondRes != null ? constCondRes : condExp.evaluate(ec);
   ExpResult trueRes = constTrueRes != null ? constTrueRes : trueExp.evaluate(ec);
   ExpResult falseRes = constFalseRes != null ? constFalseRes : falseExp.evaluate(ec);
   if (condRes.value == 0) return falseRes;
   else return trueRes;
 }
예제 #2
0
  public static Assignment parseAssignment(ParseContext context, String input) throws ExpError {
    ArrayList<ExpTokenizer.Token> ts;
    ts = ExpTokenizer.tokenize(input);

    TokenList tokens = new TokenList(ts);

    ExpTokenizer.Token nextTok = tokens.next();
    if (nextTok == null
        || (nextTok.type != ExpTokenizer.SQ_TYPE && !nextTok.value.equals("this"))) {
      throw new ExpError(input, 0, "Assignments must start with an identifier");
    }

    String[] destination = parseIdentifier(nextTok, tokens, new Expression(input));

    nextTok = tokens.next();
    if (nextTok == null || nextTok.type != ExpTokenizer.SYM_TYPE || !nextTok.value.equals("=")) {
      throw new ExpError(input, nextTok.pos, "Expected '=' in assignment");
    }

    Assignment ret = new Assignment();
    ret.destination = destination;
    ret.value = new Expression(input);

    ExpNode expNode = parseExp(context, tokens, 0, ret.value);

    expNode.walk(CONST_OP);
    expNode =
        CONST_OP.updateRef(
            expNode); // Finally, give the entire expression a chance to optimize itself into a
                      // constant

    ret.value.setRootNode(expNode);

    return ret;
  }
예제 #3
0
 void printInfix() {
   // Print the expression, in parentheses.
   System.out.print('(');
   left.printInfix();
   System.out.print(" " + op + " ");
   right.printInfix();
   System.out.print(')');
 }
예제 #4
0
    @Override
    void walk(ExpressionWalker w) throws ExpError {
      lSubExp.walk(w);
      rSubExp.walk(w);

      lSubExp = w.updateRef(lSubExp);
      rSubExp = w.updateRef(rSubExp);

      w.visit(this);
    }
예제 #5
0
 void printStackCommands() {
   // To evaluate the expression on a stack machine, first do
   // whatever is necessary to evaluate the left operand, leaving
   // the answer on the stack.  Then do the same thing for the
   // second operand.  Then apply the operator (which means popping
   // the operands, applying the operator, and pushing the result).
   left.printStackCommands();
   right.printStackCommands();
   System.out.println("  Operator " + op);
 }
예제 #6
0
    @Override
    void walk(ExpressionWalker w) throws ExpError {
      condExp.walk(w);
      trueExp.walk(w);
      falseExp.walk(w);

      condExp = w.updateRef(condExp);
      trueExp = w.updateRef(trueExp);
      falseExp = w.updateRef(falseExp);

      w.visit(this);
    }
예제 #7
0
  public static void main(String[] args) {

    while (true) {
      System.out.println("\n\nEnter an expression, or press return to end.");
      System.out.print("\n?  ");
      TextIO.skipBlanks();
      if (TextIO.peek() == '\n') break;
      try {
        ExpNode exp = expressionTree();
        TextIO.skipBlanks();
        if (TextIO.peek() != '\n') throw new ParseError("Extra data after end of expression.");
        TextIO.getln();
        ExpNode deriv = exp.derivative();
        System.out.println("\nA fully parenthesized expression for the derivative is:");
        System.out.print("   ");
        deriv.printInfix();
        System.out.println();
        System.out.println("\nValue of derivative at x = 0 is " + deriv.value(0));
        System.out.println("Value of derivative at x = 1 is " + deriv.value(1));
        System.out.println("Value of derivative at x = 2 is " + deriv.value(2));
        System.out.println("Value of derivative at x = 3 is " + deriv.value(3));
        System.out.println("\nOrder of postfix evaluation for derivative is:\n");
        deriv.printStackCommands();
      } catch (ParseError e) {
        System.out.println("\n*** Error in input:    " + e.getMessage());
        System.out.println("*** Discarding input:  " + TextIO.getln());
      }
    }

    System.out.println("\n\nDone.");
  } // end main()
예제 #8
0
 void printStackCommands() {
   // To evaluate this expression on a stack machine, first do
   // whatever is necessary to evaluate the operand, leaving the
   // operand on the stack.  Then apply the unary minus (which means
   // popping the operand, negating it, and pushing the result).
   operand.printStackCommands();
   System.out.println("  Unary minus");
 }
예제 #9
0
 double value(double xValue) {
   // The value is obtained by evaluating the left and right
   // operands and combining the values with the operator.
   double x = left.value(xValue);
   double y = right.value(xValue);
   switch (op) {
     case '+':
       return x + y;
     case '-':
       return x - y;
     case '*':
       return x * y;
     case '/':
       return x / y;
     default:
       return Double.NaN; // Bad operator!
   }
 }
예제 #10
0
  /**
   * The main entry point to the expression parsing system, will either return a valid expression
   * that can be evaluated, or throw an error.
   */
  public static Expression parseExpression(ParseContext context, String input) throws ExpError {
    ArrayList<ExpTokenizer.Token> ts;
    ts = ExpTokenizer.tokenize(input);

    TokenList tokens = new TokenList(ts);

    Expression ret = new Expression(input);
    ExpNode expNode = parseExp(context, tokens, 0, ret);

    // Make sure we've parsed all the tokens
    ExpTokenizer.Token peeked = tokens.peek();
    if (peeked != null) {
      throw new ExpError(input, peeked.pos, "Unexpected additional values");
    }

    expNode.walk(CONST_OP);
    expNode =
        CONST_OP.updateRef(
            expNode); // Finally, give the entire expression a chance to optimize itself into a
                      // constant
    ret.setRootNode(expNode);
    return ret;
  }
예제 #11
0
    public ExpResult evaluate(EvalContext ec) throws ExpError {
      synchronized (executingThreads) {
        if (executingThreads.contains(Thread.currentThread())) {
          throw new ExpError(null, 0, "Expression recursion detected for expression: %s", source);
        }

        executingThreads.add(Thread.currentThread());
      }
      ExpResult res = null;
      try {
        res = rootNode.evaluate(ec);
      } finally {
        synchronized (executingThreads) {
          executingThreads.remove(Thread.currentThread());
        }
      }
      return res;
    }
예제 #12
0
 ExpNode derivative() {
   // Apply the derivative formulas.
   switch (op) {
     case '+':
       return new BinOpNode('+', left.derivative(), right.derivative());
     case '-':
       return new BinOpNode('-', left.derivative(), right.derivative());
     case '*':
       return new BinOpNode(
           '+',
           new BinOpNode('*', left, right.derivative()),
           new BinOpNode('*', right, left.derivative()));
     case '/':
       return new BinOpNode(
           '/',
           new BinOpNode(
               '-',
               new BinOpNode('*', right, left.derivative()),
               new BinOpNode('*', left, right.derivative())),
           new BinOpNode('*', right, right));
     default:
       return null;
   }
 }
예제 #13
0
 /**
  * Evaluate an object.
  *
  * @param object
  * @return
  * @throws JParseException
  */
 public boolean evaluate(T object) throws JParseException {
   return exp.value(object);
 }
예제 #14
0
 /**
  * Evaluate a Map object's Entry.
  *
  * @param object
  * @return
  * @throws JParseException
  */
 public boolean evaluate(Map.Entry<T, V> object) throws JParseException {
   return exp.value(object);
 }
예제 #15
0
 double value(double xValue) {
   // The value is the negative of the value of the operand.
   double neg = operand.value(xValue);
   return -neg;
 }
예제 #16
0
 void printInfix() {
   // Print the expression, in parentheses.
   System.out.print("(-");
   operand.printInfix();
   System.out.print(')');
 }
예제 #17
0
 @Override
 public ExpResult evaluate(EvalContext ec) throws ExpError {
   ExpResult lRes = lConstVal != null ? lConstVal : lSubExp.evaluate(ec);
   ExpResult rRes = rConstVal != null ? rConstVal : rSubExp.evaluate(ec);
   return func.apply(context, lRes, rRes, exp.source, tokenPos);
 }
예제 #18
0
 @Override
 public ExpResult evaluate(EvalContext ec) throws ExpError {
   return func.apply(context, subExp.evaluate(ec));
 }
예제 #19
0
 ExpNode derivative() {
   // The derivative of -A is -(derivative of A).
   return new UnaryMinusNode(operand.derivative());
 }