def _evaluate_infix_expression(operator: str, left: Object, right: Object) -> Object: if left.type() == ObjectType.INTEGER \ and right.type() == ObjectType.INTEGER: return _evaluate_integer_infix_expression(operator, left, right) if left.type() == ObjectType.STRING \ and right.type() == ObjectType.STRING: return _evaluate_string_infix_expression(operator, left, right) elif operator == "==" or operator == "===": return _to_boolean_object(left is right) elif operator == "!=" or operator == "!==": return _to_boolean_object(left is not right) elif left.type() != right.type(): return _new_error(_TYPE_MISMATCH, [left.type().name, operator, right.type().name]) else: return _new_error(_UNKNOWN_INFIX_OPERATOR, [left.type().name, operator, right.type().name])
def _evaluate_integer_infix_expression(operator: str, left: Object, right: Object, line_evaluated: int) -> Object: left_value = int = cast(Integer, left).value right_value = int = cast(Integer, right).value if operator == '+': return Integer(left_value + right_value) elif operator == '-': return Integer(left_value - right_value) elif operator == '*': return Integer(left_value * right_value) elif operator == '/': return Integer(left_value // right_value) #divicio de enteros elif operator == '<': return _to_boolean_object(left_value < right_value) elif operator == '>': return _to_boolean_object(left_value > right_value) elif operator == '==': return _to_boolean_object(left_value == right_value) elif operator == '!=': return _to_boolean_object(left_value != right_value) else: return _new_error(_UNKNOWN_INFIX_OPERATOR, [left.type().name, operator, right.type().name], line_evaluated)
def _evaluate_string_infix_expression(operator: str, left: Object, right: Object) -> Object: left_value: str = cast(String, left).value right_value: str = cast(String, right).value if operator == '+': return String(left_value + right_value) elif operator == '==': return _to_boolean_object(left_value == right_value) elif operator == '!=': return _to_boolean_object(left_value != right_value) else: return _new_error(_UNKNOWN_INFIX_OPERATOR, [left.type().name, operator, right.type().name])
def _evaluate_minus_operator_expression(right: Object) -> Object: if type(right) != Integer: return _new_error(_UNKNOWN_PREFIX_OPERATOR, ['-', right.type().name]) right = cast(Integer, right) return Integer(-right.value)
def _evaluate_prefix_expression(operator: str, right: Object) -> Object: if operator == '!': return _evaluate_bang_operator_expression(right) elif operator == '-': return _evaluate_minus_operator_expression(right) else: return _new_error(_UNKNOWN_PREFIX_OPERATOR, [operator, right.type().name])
def _evaluate_integer_infix_expression(operator: str, left: Object, right: Object) -> Object: left_value: int = cast(Integer, left).value right_value: int = cast(Integer, right).value if operator == "+": return Integer(left_value + right_value) elif operator == "-": return Integer(left_value - right_value) elif operator == "*": return Integer(left_value * right_value) elif operator == "/": return Integer(left_value // right_value) elif operator == "<": return _to_boolean_object(left_value < right_value) elif operator == ">": return _to_boolean_object(left_value > right_value) elif operator == "<=": return _to_boolean_object(left_value <= right_value) elif operator == ">=": return _to_boolean_object(left_value >= right_value) elif operator == "==" or operator == "===": return _to_boolean_object(left_value == right_value) elif operator == "!=" or operator == "!==": return _to_boolean_object(left_value != right_value) else: return _new_error(_UNKNOWN_INFIX_OPERATOR, [left.type().name, operator, right.type().name])
def _apply_function(fn: Object, args: List[Object]) -> Object: if type(fn) == Function: fn = cast(Function, fn) extended_environment = _extend_function_environment(fn, args) evaluated = evaluate(fn.body, extended_environment) assert evaluated is not None return _unwrap_return_value(evaluated) elif type(fn) == Builtin: fn = cast(Builtin, fn) return fn.fn(*args) else: return _new_error(_NOT_A_FUNCTION, [fn.type().name])