def int_binary_op(op: str, c_func_name: str, result_type: RType = int_rprimitive) -> None: binary_op(op=op, arg_types=[int_rprimitive, int_rprimitive], result_type=result_type, error_kind=ERR_NEVER, format_str='{dest} = {args[0]} %s {args[1]} :: int' % op, emit=simple_emit('{dest} = %s({args[0]}, {args[1]});' % c_func_name))
def int_binary_op(op: str, c_func_name: str, result_type: RType = int_rprimitive, error_kind: int = ERR_NEVER) -> None: binary_op(op=op, arg_types=[int_rprimitive, int_rprimitive], result_type=result_type, error_kind=error_kind, format_str='{dest} = {args[0]} %s {args[1]} :: int' % op, emit=call_emit(c_func_name))
def int_compare_op(op: str, c_func_name: str) -> None: int_binary_op(op, c_func_name, bool_rprimitive) # Generate a straight compare if we know both sides are short binary_op( op=op, arg_types=[short_int_rprimitive, short_int_rprimitive], result_type=bool_rprimitive, error_kind=ERR_NEVER, format_str='{dest} = {args[0]} %s {args[1]} :: short_int' % op, emit=simple_emit( '{dest} = (Py_ssize_t){args[0]} %s (Py_ssize_t){args[1]};' % op), priority=2)
arg_types=[], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPy_FetchStopIterationValue')) # # Fallback primitive operations that operate on 'object' operands # for op, opid in [('==', 'Py_EQ'), ('!=', 'Py_NE'), ('<', 'Py_LT'), ('<=', 'Py_LE'), ('>', 'Py_GT'), ('>=', 'Py_GE')]: # The result type is 'object' since that's what PyObject_RichCompare returns. binary_op( op=op, arg_types=[object_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit( '{dest} = PyObject_RichCompare({args[0]}, {args[1]}, %s);' % opid), priority=0) for op, funcname in [('+', 'PyNumber_Add'), ('-', 'PyNumber_Subtract'), ('*', 'PyNumber_Multiply'), ('//', 'PyNumber_FloorDivide'), ('/', 'PyNumber_TrueDivide'), ('%', 'PyNumber_Remainder'), ('<<', 'PyNumber_Lshift'), ('>>', 'PyNumber_Rshift'), ('&', 'PyNumber_And'), ('^', 'PyNumber_Xor'), ('|', 'PyNumber_Or')]: binary_op(op=op, arg_types=[object_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC,
result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=emit_get_item) dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=simple_emit( '{dest} = PyDict_SetItem({args[0]}, {args[1]}, {args[2]}) >= 0;')) binary_op( op='in', arg_types=[object_rprimitive, dict_rprimitive], result_type=bool_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = {args[0]} in {args[1]} :: dict', emit=negative_int_emit('{dest} = PyDict_Contains({args[1]}, {args[0]});')) # NOTE: PyDict_Update is technically not equivalent to update, but the cases where it # differs (when the second argument has no keys) should never typecheck for us, so the # difference is irrelevant. dict_update_op = method_op( name='update', arg_types=[dict_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=simple_emit('{dest} = PyDict_Update({args[0]}, {args[1]}) != -1;')) new_dict_op = func_op(name='builtins.dict',
"%s = PySequence_Repeat(%s, %s);" % (dest, lst, temp)) def emit_multiply(emitter: EmitterInterface, args: List[str], dest: str) -> None: emit_multiply_helper(emitter, dest, args[0], args[1]) def emit_multiply_reversed(emitter: EmitterInterface, args: List[str], dest: str) -> None: emit_multiply_helper(emitter, dest, args[1], args[0]) binary_op(op='*', arg_types=[list_rprimitive, int_rprimitive], result_type=list_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = {args[0]} * {args[1]} :: list', emit=emit_multiply) binary_op(op='*', arg_types=[int_rprimitive, list_rprimitive], result_type=list_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = {args[0]} * {args[1]} :: list', emit=emit_multiply_reversed) def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None: temp = emitter.temp_name() emitter.emit_declaration('long long %s;' % temp) emitter.emit_line('%s = PyList_GET_SIZE(%s);' % (temp, args[0]))
from typing import List, Callable from mypyc.ops import (object_rprimitive, str_rprimitive, bool_rprimitive, ERR_MAGIC, EmitterInterface) from mypyc.ops_primitive import func_op, binary_op, simple_emit func_op(name='builtins.str', arg_types=[object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyObject_Str({args[0]});')) binary_op(op='+', arg_types=[str_rprimitive, str_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Concat({args[0]}, {args[1]});')) def emit_str_compare( comparison: str) -> Callable[[EmitterInterface, List[str], str], None]: def emit(emitter: EmitterInterface, args: List[str], dest: str) -> None: temp = emitter.temp_name() emitter.emit_declaration('int %s;' % temp) emitter.emit_lines( '%s = PyUnicode_Compare(%s, %s);' % (temp, args[0], args[1]), 'if (%s == -1 && PyErr_Occurred())' % temp, ' %s = 2;' % dest, 'else', ' %s = (%s %s);' % (dest, temp, comparison)) return emit