Example #1
0
def int_unary_op(op: str, c_func_name: str) -> OpDescription:
    return unary_op(op=op,
                    arg_type=int_rprimitive,
                    result_type=int_rprimitive,
                    error_kind=ERR_NEVER,
                    format_str='{dest} = %s{args[0]} :: int' % op,
                    emit=call_emit(c_func_name))
Example #2
0
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))
Example #3
0
# Get the type object for 'builtins.int'.
# For ordinary calls to int() we use a name_ref to the type
name_ref_op('builtins.int',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyLong_Type', target_type='PyObject *'),
            is_borrowed=True)

# Convert from a float to int. We could do a bit better directly.
func_op(
    name='builtins.int',
    arg_types=[float_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyLong_FromFloat'),
    priority=1)

# int(string)
func_op(
    name='builtins.int',
    arg_types=[str_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyLong_FromStr'),
    priority=1)

# int(string, base)
func_op(
    name='builtins.int',
    arg_types=[str_rprimitive, int_rprimitive],
Example #4
0
                                       call_negative_bool_emit, name_emit,
                                       c_custom_op, c_method_op, c_function_op)

# Get the 'dict' type object.
name_ref_op('builtins.dict',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyDict_Type', target_type="PyObject *"),
            is_borrowed=True)

# dict[key]
dict_get_item_op = method_op(name='__getitem__',
                             arg_types=[dict_rprimitive, object_rprimitive],
                             result_type=object_rprimitive,
                             error_kind=ERR_MAGIC,
                             emit=call_emit('CPyDict_GetItem'))

# dict[key] = value
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=call_negative_bool_emit('CPyDict_SetItem'))

# key in dict
binary_op(
    op='in',
    arg_types=[object_rprimitive, dict_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_MAGIC,
Example #5
0
c_method_op(name='__getitem__',
            arg_types=[list_rprimitive, short_int_rprimitive],
            return_type=object_rprimitive,
            c_function_name='CPyList_GetItemShort',
            error_kind=ERR_MAGIC,
            priority=2)

# This is unsafe because it assumes that the index is a non-negative short integer
# that is in-bounds for the list.
list_get_item_unsafe_op = custom_op(
    name='__getitem__',
    arg_types=[list_rprimitive, short_int_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_NEVER,
    format_str='{dest} = {args[0]}[{args[1]}] :: unsafe list',
    emit=call_emit('CPyList_GetItemUnsafe'))

# list[index] = obj
list_set_item_op = c_method_op(
    name='__setitem__',
    arg_types=[list_rprimitive, int_rprimitive, object_rprimitive],
    return_type=bool_rprimitive,
    c_function_name='CPyList_SetItem',
    error_kind=ERR_FALSE,
    steals=[False, False, True])

# list.append(obj)
list_append_op = c_method_op(name='append',
                             arg_types=[list_rprimitive, object_rprimitive],
                             return_type=c_int_rprimitive,
                             c_function_name='PyList_Append',
Example #6
0
c_method_op(name='__getitem__',
            arg_types=[list_rprimitive, short_int_rprimitive],
            return_type=object_rprimitive,
            c_function_name='CPyList_GetItemShort',
            error_kind=ERR_MAGIC,
            priority=2)

# This is unsafe because it assumes that the index is a non-negative short integer
# that is in-bounds for the list.
list_get_item_unsafe_op = custom_op(
    name='__getitem__',
    arg_types=[list_rprimitive, short_int_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_NEVER,
    format_str='{dest} = {args[0]}[{args[1]}] :: unsafe list',
    emit=call_emit('CPyList_GetItemUnsafe'))

# list[index] = obj
list_set_item_op = c_method_op(
    name='__setitem__',
    arg_types=[list_rprimitive, int_rprimitive, object_rprimitive],
    return_type=bool_rprimitive,
    c_function_name='CPyList_SetItem',
    error_kind=ERR_FALSE,
    steals=[False, False, True])

# list.append(obj)
list_append_op = method_op(name='append',
                           arg_types=[list_rprimitive, object_rprimitive],
                           result_type=bool_rprimitive,
                           error_kind=ERR_FALSE,
Example #7
0

# Get the 'dict' type object.
name_ref_op('builtins.dict',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=simple_emit('{dest} = (PyObject *)&PyDict_Type;'),
            is_borrowed=True)

# dict[key]
dict_get_item_op = method_op(
    name='__getitem__',
    arg_types=[dict_rprimitive, object_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyDict_GetItem'))

# dict[key] = value
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=call_negative_bool_emit('CPyDict_SetItem'))

# key in dict
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',
Example #8
0
)
from mypyc.ops import ERR_MAGIC, ERR_FALSE, ERR_NEVER, EmitterInterface
from mypyc.rtypes import object_rprimitive, bool_rprimitive, set_rprimitive, int_rprimitive
from typing import List

new_set_op = func_op(name='builtins.set',
                     arg_types=[],
                     result_type=set_rprimitive,
                     error_kind=ERR_MAGIC,
                     emit=simple_emit('{dest} = PySet_New(NULL);'))

func_op(name='builtins.set',
        arg_types=[object_rprimitive],
        result_type=set_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('PySet_New'))

func_op(name='builtins.frozenset',
        arg_types=[object_rprimitive],
        result_type=object_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('PyFrozenSet_New'))


def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None:
    temp = emitter.temp_name()
    emitter.emit_declaration('Py_ssize_t %s;' % temp)
    emitter.emit_line('%s = PySet_GET_SIZE(%s);' % (temp, args[0]))
    emitter.emit_line('%s = CPyTagged_ShortFromSsize_t(%s);' % (dest, temp))

Example #9
0
    'raise_exception_with_tb({args[0]}, {args[1]}, {args[2]}); {dest} = 0',
    emit=call_and_fail_emit('CPyErr_SetObjectAndTraceback'))

# Reraise the currently raised exception.
reraise_exception_op = custom_op(arg_types=[],
                                 result_type=bool_rprimitive,
                                 error_kind=ERR_FALSE,
                                 format_str='reraise_exc; {dest} = 0',
                                 emit=call_and_fail_emit('CPy_Reraise'))

# Propagate exception if the CPython error indicator is set (an exception was raised).
no_err_occurred_op = custom_op(arg_types=[],
                               result_type=bool_rprimitive,
                               error_kind=ERR_FALSE,
                               format_str='{dest} = no_err_occurred',
                               emit=call_emit('CPy_NoErrOccured'))

# Assert that the error indicator has been set.
assert_err_occured_op = custom_op(
    arg_types=[],
    result_type=void_rtype,
    error_kind=ERR_NEVER,
    format_str='assert_err_occurred',
    emit=simple_emit(
        'assert(PyErr_Occurred() != NULL && "failure w/o err!");'))

# Keep propagating a raised exception by unconditionally giving an error value.
# This doesn't actually raise an exception.
keep_propagating_op = custom_op(arg_types=[],
                                result_type=bool_rprimitive,
                                error_kind=ERR_FALSE,
Example #10
0
# Construct a list from values: [item1, item2, ....]
new_list_op = custom_op(arg_types=[object_rprimitive],
                        result_type=list_rprimitive,
                        is_var_arg=True,
                        error_kind=ERR_MAGIC,
                        steals=True,
                        format_str='{dest} = [{comma_args}]',
                        emit=emit_new)

# list[index] (for an integer index)
list_get_item_op = method_op(name='__getitem__',
                             arg_types=[list_rprimitive, int_rprimitive],
                             result_type=object_rprimitive,
                             error_kind=ERR_MAGIC,
                             emit=call_emit('CPyList_GetItem'))

# Version with no int bounds check for when it is known to be short
method_op(name='__getitem__',
          arg_types=[list_rprimitive, short_int_rprimitive],
          result_type=object_rprimitive,
          error_kind=ERR_MAGIC,
          emit=call_emit('CPyList_GetItemShort'),
          priority=2)

# This is unsafe because it assumes that the index is a non-negative short integer
# that is in-bounds for the list.
list_get_item_unsafe_op = custom_op(
    name='__getitem__',
    arg_types=[list_rprimitive, short_int_rprimitive],
    result_type=object_rprimitive,
Example #11
0
    call_negative_bool_emit,
)

# Get the 'builtins.list' type object.
name_ref_op('builtins.list',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyList_Type', target_type='PyObject *'),
            is_borrowed=True)

# list(obj)
to_list = func_op(name='builtins.list',
                  arg_types=[object_rprimitive],
                  result_type=list_rprimitive,
                  error_kind=ERR_MAGIC,
                  emit=call_emit('PySequence_List'))


def emit_new(emitter: EmitterInterface, args: List[str], dest: str) -> None:
    # TODO: This would be better split into multiple smaller ops.
    emitter.emit_line('%s = PyList_New(%d); ' % (dest, len(args)))
    emitter.emit_line('if (likely(%s != NULL)) {' % dest)
    for i, arg in enumerate(args):
        emitter.emit_line('PyList_SET_ITEM(%s, %s, %s);' % (dest, i, arg))
    emitter.emit_line('}')


# Construct a list from values: [item1, item2, ....]
new_list_op = custom_op(arg_types=[object_rprimitive],
                        result_type=list_rprimitive,
                        is_var_arg=True,
Example #12
0
# str.join(obj)
method_op(
    name='join',
    arg_types=[str_rprimitive, object_rprimitive],
    result_type=str_rprimitive,
    error_kind=ERR_MAGIC,
    emit=simple_emit('{dest} = PyUnicode_Join({args[0]}, {args[1]});'))

# str[index] (for an int index)
method_op(
    name='__getitem__',
    arg_types=[str_rprimitive, int_rprimitive],
    result_type=str_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyStr_GetItem'))

# str.split(...)
str_split_types = [str_rprimitive, str_rprimitive, int_rprimitive]  # type: List[RType]
str_split_emits = [simple_emit('{dest} = PyUnicode_Split({args[0]}, NULL, -1);'),
                   simple_emit('{dest} = PyUnicode_Split({args[0]}, {args[1]}, -1);'),
                   simple_emit('{dest} = CPyStr_Split({args[0]}, {args[1]}, {args[2]});')] \
                   # type: List[EmitCallback]
for i in range(len(str_split_types)):
    method_op(
        name='split',
        arg_types=str_split_types[0:i+1],
        result_type=list_rprimitive,
        error_kind=ERR_MAGIC,
        emit=str_split_emits[i])
Example #13
0
from typing import List

from mypyc.ir.ops import (
    EmitterInterface, ERR_NEVER, ERR_MAGIC
)
from mypyc.ir.rtypes import tuple_rprimitive, int_rprimitive, list_rprimitive, object_rprimitive
from mypyc.primitives.registry import func_op, method_op, custom_op, call_emit, simple_emit


tuple_get_item_op = method_op(
    name='__getitem__',
    arg_types=[tuple_rprimitive, int_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPySequenceTuple_GetItem'))


new_tuple_op = custom_op(
    arg_types=[object_rprimitive],
    result_type=tuple_rprimitive,
    is_var_arg=True,
    error_kind=ERR_MAGIC,
    steals=False,
    format_str='{dest} = ({comma_args}) :: tuple',
    emit=simple_emit('{dest} = PyTuple_Pack({num_args}{pre_comma_args});'))


def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None:
    temp = emitter.temp_name()
    emitter.emit_declaration('Py_ssize_t %s;' % temp)
Example #14
0
    simple_emit,
    call_emit,
    call_negative_bool_emit,
)

name_ref_op('builtins.list',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=simple_emit('{dest} = (PyObject *)&PyList_Type;'),
            is_borrowed=True)

to_list = func_op(name='builtins.list',
                  arg_types=[object_rprimitive],
                  result_type=list_rprimitive,
                  error_kind=ERR_MAGIC,
                  emit=call_emit('PySequence_List'))


def emit_new(emitter: EmitterInterface, args: List[str], dest: str) -> None:
    # TODO: This would be better split into multiple smaller ops.
    emitter.emit_line('%s = PyList_New(%d); ' % (dest, len(args)))
    emitter.emit_line('if (likely(%s != NULL)) {' % dest)
    for i, arg in enumerate(args):
        emitter.emit_line('PyList_SET_ITEM(%s, %s, %s);' % (dest, i, arg))
    emitter.emit_line('}')


new_list_op = custom_op(arg_types=[object_rprimitive],
                        result_type=list_rprimitive,
                        is_var_arg=True,
                        error_kind=ERR_MAGIC,
Example #15
0
# I guess unboxing ourselves would save a check and branch though?

# Get the type object for 'builtins.int'.
# For ordinary calls to int() we use a name_ref to the type
name_ref_op('builtins.int',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=simple_emit('{dest} = (PyObject *)&PyLong_Type;'),
            is_borrowed=True)

# Convert from a float to int. We could do a bit better directly.
func_op(name='builtins.int',
        arg_types=[float_rprimitive],
        result_type=object_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('CPyLong_FromFloat'),
        priority=1)

# int(string)
func_op(name='builtins.int',
        arg_types=[str_rprimitive],
        result_type=object_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('CPyLong_FromStr'),
        priority=1)

# int(string, base)
func_op(name='builtins.int',
        arg_types=[str_rprimitive, int_rprimitive],
        result_type=object_rprimitive,
        error_kind=ERR_MAGIC,
Example #16
0
    arg_types=[object_rprimitive],
    result_type=object_rprimitive,
    is_var_arg=True,
    error_kind=ERR_MAGIC,
    format_str='{dest} = py_call({comma_args})',
    emit=simple_emit(
        '{dest} = PyObject_CallFunctionObjArgs({comma_args}, NULL);'))

# Call callable object with positional + keyword args: func(*args, **kwargs)
# Arguments are (func, *args tuple, **kwargs dict).
py_call_with_kwargs_op = custom_op(
    arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    format_str='{dest} = py_call_with_kwargs({args[0]}, {args[1]}, {args[2]})',
    emit=call_emit('PyObject_Call'))

# Call method with positional arguments: obj.method(arg1, ...)
# Arguments are (object, attribute name, arg1, ...).
py_method_call_op = custom_op(
    arg_types=[object_rprimitive],
    result_type=object_rprimitive,
    is_var_arg=True,
    error_kind=ERR_MAGIC,
    format_str='{dest} = py_method_call({comma_args})',
    emit=simple_emit(
        '{dest} = CPyObject_CallMethodObjArgs({comma_args}, NULL);'))

# len(obj)
generic_len_op = c_custom_op(arg_types=[object_rprimitive],
                             return_type=int_rprimitive,
Example #17
0
                                       name_ref_op, method_op, call_emit,
                                       name_emit, c_method_op)

# Get the 'str' type object.
name_ref_op('builtins.str',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyUnicode_Type', target_type='PyObject *'),
            is_borrowed=True)

# str(obj)
func_op(name='builtins.str',
        arg_types=[object_rprimitive],
        result_type=str_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('PyObject_Str'))

# str1 + str2
binary_op(op='+',
          arg_types=[str_rprimitive, str_rprimitive],
          result_type=str_rprimitive,
          error_kind=ERR_MAGIC,
          emit=call_emit('PyUnicode_Concat'))

# str.join(obj)
c_method_op(name='join',
            arg_types=[str_rprimitive, object_rprimitive],
            return_type=str_rprimitive,
            c_function_name='PyUnicode_Join',
            error_kind=ERR_MAGIC)
Example #18
0
        '{dest} = (PyObject*) _PyType_CalculateMetaclass((PyTypeObject *){args[0]}, {args[1]});'
    ),
    is_borrowed=True)

# Import a module
import_op = c_custom_op(arg_types=[str_rprimitive],
                        return_type=object_rprimitive,
                        c_function_name='PyImport_Import',
                        error_kind=ERR_MAGIC)

# Get the sys.modules dictionary
get_module_dict_op = custom_op(name='get_module_dict',
                               arg_types=[],
                               result_type=dict_rprimitive,
                               error_kind=ERR_NEVER,
                               emit=call_emit('PyImport_GetModuleDict'),
                               is_borrowed=True)

# isinstance(obj, cls)
c_function_op(name='builtins.isinstance',
              arg_types=[object_rprimitive, object_rprimitive],
              return_type=c_int_rprimitive,
              c_function_name='PyObject_IsInstance',
              error_kind=ERR_NEG_INT,
              truncated_type=bool_rprimitive)

# Faster isinstance(obj, cls) that only works with native classes and doesn't perform
# type checking of the type argument.
fast_isinstance_op = func_op(
    'builtins.isinstance',
    arg_types=[object_rprimitive, object_rprimitive],
Example #19
0
                                 emit=name_emit('Py_NotImplemented'),
                                 is_borrowed=True)

# id(obj)
c_function_op(name='builtins.id',
              arg_types=[object_rprimitive],
              return_type=int_rprimitive,
              c_function_name='CPyTagged_Id',
              error_kind=ERR_NEVER)

# Return the result of obj.__await()__ or obj.__iter__() (if no __await__ exists)
coro_op = custom_op(name='get_coroutine_obj',
                    arg_types=[object_rprimitive],
                    result_type=object_rprimitive,
                    error_kind=ERR_MAGIC,
                    emit=call_emit('CPy_GetCoro'))

# Do obj.send(value), or a next(obj) if second arg is None.
# (This behavior is to match the PEP 380 spec for yield from.)
# Like next_raw_op, don't swallow StopIteration,
# but also don't propagate an error.
# Can return NULL: see next_op.
send_op = custom_op(name='send',
                    arg_types=[object_rprimitive, object_rprimitive],
                    result_type=object_rprimitive,
                    error_kind=ERR_NEVER,
                    emit=call_emit('CPyIter_Send'))

# This is sort of unfortunate but oh well: yield_from_except performs most of the
# error handling logic in `yield from` operations. It returns a bool and a value.
# If the bool is true, then a StopIteration was received and we should return.
Example #20
0
                        result_type=object_rprimitive,
                        error_kind=ERR_NEVER,
                        emit=name_emit('Py_Ellipsis'),
                        is_borrowed=True)

not_implemented_op = name_ref_op(name='builtins.NotImplemented',
                                 result_type=object_rprimitive,
                                 error_kind=ERR_NEVER,
                                 emit=name_emit('Py_NotImplemented'),
                                 is_borrowed=True)

func_op(name='builtins.id',
        arg_types=[object_rprimitive],
        result_type=int_rprimitive,
        error_kind=ERR_NEVER,
        emit=call_emit('CPyTagged_Id'))

iter_op = func_op(name='builtins.iter',
                  arg_types=[object_rprimitive],
                  result_type=object_rprimitive,
                  error_kind=ERR_MAGIC,
                  emit=call_emit('PyObject_GetIter'))

coro_op = custom_op(name='get_coroutine_obj',
                    arg_types=[object_rprimitive],
                    result_type=object_rprimitive,
                    error_kind=ERR_MAGIC,
                    emit=call_emit('CPy_GetCoro'))

# Although the error_kind is set to be ERR_NEVER, this can actually
# return NULL, and thus it must be checked using Branch.IS_ERROR.
Example #21
0
# These int constructors produce object_rprimitives that then need to be unboxed
# I guess unboxing ourselves would save a check and branch though?

# For ordinary calls to int() we use a name_ref to the type
name_ref_op('builtins.int',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=simple_emit('{dest} = (PyObject *)&PyLong_Type;'),
            is_borrowed=True)

# Convert from a float. We could do a bit better directly.
func_op(name='builtins.int',
        arg_types=[float_rprimitive],
        result_type=object_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('CPyLong_FromFloat'),
        priority=1)


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))

Example #22
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,
              emit=call_emit(funcname),
              priority=0)

for op, funcname in [('+=', 'PyNumber_InPlaceAdd'),
                     ('-=', 'PyNumber_InPlaceSubtract'),
                     ('*=', 'PyNumber_InPlaceMultiply'),
                     ('@=', 'PyNumber_InPlaceMatrixMultiply'),
                     ('//=', 'PyNumber_InPlaceFloorDivide'),
                     ('/=', 'PyNumber_InPlaceTrueDivide'),
                     ('%=', 'PyNumber_InPlaceRemainder'),
                     ('<<=', 'PyNumber_InPlaceLshift'),
                     ('>>=', 'PyNumber_InPlaceRshift'),
                     ('&=', 'PyNumber_InPlaceAnd'),
                     ('^=', 'PyNumber_InPlaceXor'),
                     ('|=', 'PyNumber_InPlaceOr')]:
    binary_op(op=op,
Example #23
0
            c_function_name='PyUnicode_Join',
            error_kind=ERR_MAGIC)

# str[index] (for an int index)
c_method_op(name='__getitem__',
            arg_types=[str_rprimitive, int_rprimitive],
            return_type=str_rprimitive,
            c_function_name='CPyStr_GetItem',
            error_kind=ERR_MAGIC)

# str.split(...)
str_split_types = [str_rprimitive, str_rprimitive,
                   int_rprimitive]  # type: List[RType]
str_split_emits = [simple_emit('{dest} = PyUnicode_Split({args[0]}, NULL, -1);'),
                   simple_emit('{dest} = PyUnicode_Split({args[0]}, {args[1]}, -1);'),
                   call_emit('CPyStr_Split')] \
                   # type: List[EmitCallback]

for i in range(len(str_split_types)):
    method_op(name='split',
              arg_types=str_split_types[0:i + 1],
              result_type=list_rprimitive,
              error_kind=ERR_MAGIC,
              emit=str_split_emits[i])

# str1 += str2
#
# PyUnicodeAppend makes an effort to reuse the LHS when the refcount
# is 1. This is super dodgy but oh well, the interpreter does it.
c_binary_op(name='+=',
            arg_types=[str_rprimitive, str_rprimitive],
Example #24
0
    name_emit,
)

# Get the 'dict' type object.
name_ref_op('builtins.dict',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyDict_Type', target_type="PyObject *"),
            is_borrowed=True)

# dict[key]
dict_get_item_op = method_op(name='__getitem__',
                             arg_types=[dict_rprimitive, object_rprimitive],
                             result_type=object_rprimitive,
                             error_kind=ERR_MAGIC,
                             emit=call_emit('CPyDict_GetItem'))

# dict[key] = value
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=call_negative_bool_emit('CPyDict_SetItem'))

# key in dict
binary_op(
    op='in',
    arg_types=[object_rprimitive, dict_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_MAGIC,