CODE-0006 · claude-sonnet-4-6 (high)
def eval_expr(s):
    """Evaluate an arithmetic expression string and return its numeric value."""

    # ------------------------------------------------------------------ #
    #  Tokenizer                                                           #
    # ------------------------------------------------------------------ #
    def tokenize(text):
        tokens = []
        i = 0
        n = len(text)
        while i < n:
            c = text[i]
            if c.isspace():
                i += 1
            elif c in '+-*/()':
                tokens.append(c)
                i += 1
            elif c.isdigit() or c == '.':
                j = i
                has_dot = False
                while j < n and (text[j].isdigit() or (text[j] == '.' and not has_dot)):
                    if text[j] == '.':
                        has_dot = True
                    j += 1
                num_str = text[i:j]
                if num_str == '.':
                    raise ValueError("Invalid token: '.'")
                tokens.append(float(num_str) if has_dot else int(num_str))
                i = j
            else:
                raise ValueError(f"Unknown character: {repr(c)}")
        if not tokens:
            raise ValueError("Empty expression")
        return tokens

    # ------------------------------------------------------------------ #
    #  Input validation                                                    #
    # ------------------------------------------------------------------ #
    if not s or not s.strip():
        raise ValueError("Empty expression")

    tokens = tokenize(s)
    pos = [0]                        # mutable position shared across helpers

    # ------------------------------------------------------------------ #
    #  Parser helpers                                                      #
    # ------------------------------------------------------------------ #
    def peek():
        return tokens[pos[0]] if pos[0] < len(tokens) else None

    def consume():
        tok = tokens[pos[0]]
        pos[0] += 1
        return tok

    # Grammar:
    #   expr   ::= term   (('+' | '-') term)*
    #   term   ::= factor (('*' | '/')  factor)*
    #   factor ::= ('+' | '-') factor | atom
    #   atom   ::= number | '(' expr ')'

    def parse_expr():
        left = parse_term()
        while peek() in ('+', '-'):
            op = consume()
            right = parse_term()
            left = left + right if op == '+' else left - right
        return left

    def parse_term():
        left = parse_factor()
        while peek() in ('*', '/'):
            op = consume()
            right = parse_factor()
            if op == '*':
                left = left * right
            else:
                if right == 0:
                    raise ValueError("Division by zero")
                left = left / right
        return left

    def parse_factor():
        tok = peek()
        if tok == '+':
            consume()
            return parse_factor()
        elif tok == '-':
            consume()
            return -parse_factor()
        else:
            return parse_atom()

    def parse_atom():
        tok = peek()
        if tok is None:
            raise ValueError("Unexpected end of expression")
        if tok == '(':
            consume()
            val = parse_expr()
            if peek() != ')':
                raise ValueError("Missing closing parenthesis")
            consume()
            return val
        elif isinstance(tok, (int, float)):
            consume()
            return tok
        else:
            raise ValueError(f"Unexpected token: {repr(tok)}")

    # ------------------------------------------------------------------ #
    #  Parse and finalise                                                  #
    # ------------------------------------------------------------------ #
    result = parse_expr()

    if pos[0] != len(tokens):
        raise ValueError(f"Unexpected token: {repr(tokens[pos[0]])}")

    # Return int when the result is an exact integer value.
    if isinstance(result, float) and result.is_integer():
        return int(result)
    return result