1 52 53 package freemarker.core; 54 55 import freemarker.template.*; 56 57 62 final class ArithmeticExpression extends Expression { 63 64 static final int SUBSTRACTION = 0; 65 static final int MULTIPLICATION = 1; 66 static final int DIVISION = 2; 67 static final int MODULUS = 3; 68 69 private static final char[] OPERATORS = new char[] {'-','*','/','%'}; 70 71 private final Expression left; 72 private final Expression right; 73 private final int operation; 74 75 ArithmeticExpression(Expression left, Expression right, int operation) { 76 this.left = left; 77 this.right = right; 78 this.operation = operation; 79 } 80 81 TemplateModel _getAsTemplateModel(Environment env) throws TemplateException 82 { 83 TemplateModel leftModel = left.getAsTemplateModel(env); 84 TemplateModel rightModel = right.getAsTemplateModel(env); 85 boolean leftIsNumber = (leftModel instanceof TemplateNumberModel); 86 boolean rightIsNumber = (rightModel instanceof TemplateNumberModel); 87 boolean bothNumbers = leftIsNumber && rightIsNumber; 88 if (!bothNumbers) { 89 String msg = "Error " + getStartLocation(); 90 if (!leftIsNumber) { 91 msg += "\nExpression " + left + " is not numerical"; 92 } 93 if (!rightIsNumber) { 94 msg += "\nExpression " + right + " is not numerical"; 95 } 96 throw new NonNumericalException(msg, env); 97 } 98 Number first = EvaluationUtil.getNumber(leftModel, left, env); 99 Number second = EvaluationUtil.getNumber(rightModel, right, env); 100 ArithmeticEngine ae = 101 env != null 102 ? env.getArithmeticEngine() 103 : getTemplate().getArithmeticEngine(); 104 switch (operation) { 105 case SUBSTRACTION : 106 return new SimpleNumber(ae.subtract(first, second)); 107 case MULTIPLICATION : 108 return new SimpleNumber(ae.multiply(first, second)); 109 case DIVISION : 110 return new SimpleNumber(ae.divide(first, second)); 111 case MODULUS : 112 return new SimpleNumber(ae.modulus(first, second)); 113 default: 114 throw new TemplateException("unknown operation : " + operation, env); 115 } 116 } 117 118 public String getCanonicalForm() { 119 return left.getCanonicalForm() + ' ' + OPERATORS[operation] + ' ' + right.getCanonicalForm(); 120 } 121 122 boolean isLiteral() { 123 return constantValue != null || (left.isLiteral() && right.isLiteral()); 124 } 125 126 Expression _deepClone(String name, Expression subst) { 127 return new ArithmeticExpression(left.deepClone(name, subst), right.deepClone(name, subst), operation); 128 } 129 } 130 | Popular Tags |