CODE-0006 · gemini-3.1-flash-lite (default)
import re

def eval_expr(s):
    tokens = re.findall(r'\d*\.\d+|\d+|[+\-*/()]', s)
    if not tokens:
        raise ValueError("Empty or invalid expression")

    pos = 0

    def parse_expr():
        nonlocal pos
        node = parse_term()
        while pos < len(tokens) and tokens[pos] in ('+', '-'):
            op = tokens[pos]
            pos += 1
            right = parse_term()
            if op == '+': node += right
            else: node -= right
        return node

    def parse_term():
        nonlocal pos
        node = parse_factor()
        while pos < len(tokens) and tokens[pos] in ('*', '/'):
            op = tokens[pos]
            pos += 1
            right = parse_factor()
            if op == '*': node *= right
            else:
                if right == 0: raise ValueError("Division by zero")
                node /= right
        return node

    def parse_factor():
        nonlocal pos
        if pos >= len(tokens): raise ValueError("Unexpected end of expression")
        
        token = tokens[pos]
        if token == '+':
            pos += 1
            return parse_factor()
        if token == '-':
            pos += 1
            return -parse_factor()
        if token == '(':
            pos += 1
            val = parse_expr()
            if pos >= len(tokens) or tokens[pos] != ')':
                raise ValueError("Mismatched parentheses")
            pos += 1
            return val
        
        try:
            val = float(token)
            pos += 1
            return int(val) if val.is_integer() else val
        except ValueError:
            raise ValueError(f"Unknown token: {token}")

    res = parse_expr()
    if pos < len(tokens):
        raise ValueError("Dangling operator or invalid syntax")
    
    if isinstance(res, float) and res.is_integer():
        return int(res)
    return res