def expr_value(expr):
    """
    Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),
    or 2 (y).

    'expr' must be an already-parsed expression from a Symbol, Choice, or
    MenuNode property. To evaluate an expression represented as a string, use
    Kconfig.eval_string().

    Passing subexpressions of expressions to this function works as expected.
    """
    if expr.__class__ is not tuple:
        return expr.tri_value

    if expr[0] is AND:
        v1 = expr_value(expr[1])
        # Short-circuit the n case as an optimization (~5% faster
        # allnoconfig.py and allyesconfig.py, as of writing)
        return 0 if not v1 else min(v1, expr_value(expr[2]))

    if expr[0] is OR:
        v1 = expr_value(expr[1])
        # Short-circuit the y case as an optimization
        return 2 if v1 == 2 else max(v1, expr_value(expr[2]))

    if expr[0] is NOT:
        return 2 - expr_value(expr[1])

    # Relation
    #
    # Implements <, <=, >, >= comparisons as well. These were added to
    # kconfig in 31847b67 (kconfig: allow use of relations other than
    # (in)equality).

    rel, v1, v2 = expr

    # If both operands are strings...
    if v1.orig_type is STRING and v2.orig_type is STRING:
        # ...then compare them lexicographically
        comp = _strcmp(v1.str_value, v2.str_value)
    else:
        # Otherwise, try to compare them as numbers
        try:
            comp = _sym_to_num(v1) - _sym_to_num(v2)
        except ValueError:
            # Fall back on a lexicographic comparison if the operands don't
            # parse as numbers
            comp = _strcmp(v1.str_value, v2.str_value)

    return 2*(comp == 0 if rel is EQUAL else
              comp != 0 if rel is UNEQUAL else
              comp <  0 if rel is LESS else
              comp <= 0 if rel is LESS_EQUAL else
              comp >  0 if rel is GREATER else
              comp >= 0)

    Evaluates the expression 'expr' to a tristate value. Returns 0 (n), 1 (m),
    or 2 (y).

    'expr' must be an already-parsed expression from a Symbol, Choice, or
    MenuNode property. To evaluate an expression represented as a string, use
    Kconfig.eval_string().

    Passing subexpressions of expressions to this function works as expected.
    
buildroot-external/scripts/kconfiglib.py