summaryrefslogtreecommitdiffstats
path: root/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Value.java
blob: a63387506a0748bb9e0d007488e72858c0c971dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchlib.rankingexpression.evaluation;

import com.yahoo.javacc.UnicodeUtilities;
import com.yahoo.searchlib.rankingexpression.rule.Function;
import com.yahoo.searchlib.rankingexpression.rule.TruthOperator;
import com.yahoo.tensor.Tensor;

/**
 * The result of a ranking expression evaluation.
 * Concrete subclasses of this provides implementations of these methods or throws
 * UnsupportedOperationException if the operation is not supported.
 *
 * @author  bratseth
 */
public abstract class Value {

    private boolean frozen=false;

    /** Returns this value as a double, or throws UnsupportedOperationException if it cannot be represented as a double */
    public abstract double asDouble();

    /** Returns this value as a double value, or throws UnsupportedOperationException if it cannot be represented as a double */
    public DoubleValue asDoubleValue() {
        return new DoubleValue(asDouble());
    }

    /** Returns true if this value can return itself as a double, i.e asDoubleValue will return a value and not throw */
    public abstract boolean hasDouble();

    /** Returns this value as a boolean. */
    public abstract boolean asBoolean();

    public abstract Value negate();

    public abstract Value add(Value value);

    public abstract Value subtract(Value value);

    public abstract Value multiply(Value value);

    public abstract Value divide(Value value);

    /** Perform the comparison specified by the operator between this value and the given value */
    public abstract Value compare(TruthOperator operator, Value value);

    /** Perform the given binary function on this value and the given value */
    public abstract Value function(Function function,Value value);

    /**
     * Irreversibly makes this immutable. Overriders must always call super.freeze() and return this
     *
     * @return this for convenience
     */
    public Value freeze() {
        frozen=true;
        return this;
    }

    /** Returns true if this is immutable, false otherwise */
    public final boolean isFrozen() { return frozen; }

    /** Returns this is mutable, or a mutable copy otherwise */
    public abstract Value asMutable();

    @Override
    public abstract String toString();

    @Override
    public abstract boolean equals(Object other);

    @Override
    public abstract int hashCode();

    /**
     * Parses the given string to a value and returns it.
     * Different subtypes of Value will be returned depending on the string.
     *
     * @return a mutable Value
     * @throws IllegalArgumentException if the given string is not parseable as a value
     */
    public static Value parse(String value) {
        if (value.equals("true"))
            return new BooleanValue(true);
        else if (value.equals("false"))
            return new BooleanValue(false);
        else if (value.startsWith("\"") || value.startsWith("'"))
            return new StringValue(UnicodeUtilities.unquote(value));
        else if (value.startsWith("{"))
            return new TensorValue(Tensor.from(value));
        else
            return new DoubleValue(Double.parseDouble(value));
    }

}