Esempio n. 1
0
            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],
            return_type=str_rprimitive,
            c_function_name='CPyStr_Append',
            error_kind=ERR_MAGIC,
            steals=[True, False])

Esempio n. 2
0
    name_ref_op, method_op, binary_op, func_op, custom_op,
    simple_emit, negative_int_emit, call_emit, call_negative_bool_emit,
)


# 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,
Esempio n. 3
0
new_list_op = custom_op(arg_types=[c_pyssize_t_rprimitive],
                        return_type=list_rprimitive,
                        c_function_name='PyList_New',
                        error_kind=ERR_MAGIC)

list_build_op = custom_op(arg_types=[c_pyssize_t_rprimitive],
                          return_type=list_rprimitive,
                          c_function_name='CPyList_Build',
                          error_kind=ERR_MAGIC,
                          var_arg_type=object_rprimitive,
                          steals=True)

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

# list[index] 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],
          return_type=object_rprimitive,
          c_function_name='CPyList_GetItemShort',
          error_kind=ERR_MAGIC,
          priority=2)

# list[index] that produces a borrowed result
method_op(name='__getitem__',
          arg_types=[list_rprimitive, int_rprimitive],
          return_type=object_rprimitive,
Esempio n. 4
0
    result_type=int_rprimitive,
    error_kind=ERR_NEVER,
    emit=emit_len,
)

binary_op(
    op='in',
    arg_types=[object_rprimitive, set_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_MAGIC,
    format_str='{dest} = {args[0]} in {args[1]} :: set',
    emit=negative_int_emit('{dest} = PySet_Contains({args[1]}, {args[0]});'))

method_op(name='remove',
          arg_types=[set_rprimitive, object_rprimitive],
          result_type=bool_rprimitive,
          error_kind=ERR_FALSE,
          emit=call_emit('CPySet_Remove'))

method_op(name='discard',
          arg_types=[set_rprimitive, object_rprimitive],
          result_type=bool_rprimitive,
          error_kind=ERR_FALSE,
          emit=call_negative_bool_emit('PySet_Discard'))

set_add_op = method_op(name='add',
                       arg_types=[set_rprimitive, object_rprimitive],
                       result_type=bool_rprimitive,
                       error_kind=ERR_FALSE,
                       emit=call_negative_bool_emit('PySet_Add'))
Esempio n. 5
0
            arg_types=[set_rprimitive, object_rprimitive],
            return_type=bool_rprimitive,
            c_function_name='CPySet_Remove',
            error_kind=ERR_FALSE)

# set.discard(obj)
c_method_op(name='discard',
            arg_types=[set_rprimitive, object_rprimitive],
            return_type=c_int_rprimitive,
            c_function_name='PySet_Discard',
            error_kind=ERR_NEG_INT)

# set.add(obj)
set_add_op = method_op(name='add',
                       arg_types=[set_rprimitive, object_rprimitive],
                       result_type=bool_rprimitive,
                       error_kind=ERR_FALSE,
                       emit=call_negative_bool_emit('PySet_Add'))

# set.update(obj)
#
# This is not a public API but looks like it should be fine.
set_update_op = method_op(name='update',
                          arg_types=[set_rprimitive, object_rprimitive],
                          result_type=bool_rprimitive,
                          error_kind=ERR_FALSE,
                          emit=call_negative_bool_emit('_PySet_Update'))

# set.clear()
method_op(name='clear',
          arg_types=[set_rprimitive],
Esempio n. 6
0
binary_op(name='+=',
          arg_types=[str_rprimitive, str_rprimitive],
          return_type=str_rprimitive,
          c_function_name='CPyStr_Append',
          error_kind=ERR_MAGIC,
          steals=[True, False])

unicode_compare = custom_op(arg_types=[str_rprimitive, str_rprimitive],
                            return_type=c_int_rprimitive,
                            c_function_name='PyUnicode_Compare',
                            error_kind=ERR_NEVER)

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

# str[begin:end]
str_slice_op = custom_op(
    arg_types=[str_rprimitive, int_rprimitive, int_rprimitive],
    return_type=object_rprimitive,
    c_function_name='CPyStr_GetSlice',
    error_kind=ERR_MAGIC)

# str.join(obj)
method_op(name='join',
          arg_types=[str_rprimitive, object_rprimitive],
          return_type=str_rprimitive,
          c_function_name='PyUnicode_Join',
Esempio n. 7
0
These are for varying-length tuples represented as Python tuple objects
(RPrimitive, not RTuple).
"""

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:
Esempio n. 8
0
# bytes(obj)
function_op(
    name='builtins.bytes',
    arg_types=[RUnion([list_rprimitive, dict_rprimitive, str_rprimitive])],
    return_type=bytes_rprimitive,
    c_function_name='PyBytes_FromObject',
    error_kind=ERR_MAGIC)

# bytearray(obj)
function_op(name='builtins.bytearray',
            arg_types=[object_rprimitive],
            return_type=bytes_rprimitive,
            c_function_name='PyByteArray_FromObject',
            error_kind=ERR_MAGIC)

# bytes + bytes
# bytearray + bytearray
binary_op(name='+',
          arg_types=[bytes_rprimitive, bytes_rprimitive],
          return_type=bytes_rprimitive,
          c_function_name='CPyBytes_Concat',
          error_kind=ERR_MAGIC,
          steals=[True, False])

# bytes.join(obj)
method_op(name='join',
          arg_types=[bytes_rprimitive, object_rprimitive],
          return_type=bytes_rprimitive,
          c_function_name='CPyBytes_Join',
          error_kind=ERR_MAGIC)
Esempio n. 9
0
            c_function_name='PyFrozenSet_New',
            error_kind=ERR_MAGIC)

# item in set
binary_op(name='in',
          arg_types=[object_rprimitive, set_rprimitive],
          return_type=c_int_rprimitive,
          c_function_name='PySet_Contains',
          error_kind=ERR_NEG_INT,
          truncated_type=bool_rprimitive,
          ordering=[1, 0])

# set.remove(obj)
method_op(name='remove',
          arg_types=[set_rprimitive, object_rprimitive],
          return_type=bit_rprimitive,
          c_function_name='CPySet_Remove',
          error_kind=ERR_FALSE)

# set.discard(obj)
method_op(name='discard',
          arg_types=[set_rprimitive, object_rprimitive],
          return_type=c_int_rprimitive,
          c_function_name='PySet_Discard',
          error_kind=ERR_NEG_INT)

# set.add(obj)
set_add_op = method_op(name='add',
                       arg_types=[set_rprimitive, object_rprimitive],
                       return_type=c_int_rprimitive,
                       c_function_name='PySet_Add',
Esempio n. 10
0
             emit=call_emit(funcname),
             priority=0)

unary_op(op='not',
         arg_type=object_rprimitive,
         result_type=bool_rprimitive,
         error_kind=ERR_MAGIC,
         format_str='{dest} = not {args[0]}',
         emit=call_negative_magic_emit('PyObject_Not'),
         priority=0)


# obj1[obj2]
method_op('__getitem__',
          arg_types=[object_rprimitive, object_rprimitive],
          result_type=object_rprimitive,
          error_kind=ERR_MAGIC,
          emit=call_emit('PyObject_GetItem'),
          priority=0)

# obj1[obj2] = obj3
method_op('__setitem__',
          arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
          result_type=bool_rprimitive,
          error_kind=ERR_FALSE,
          emit=call_negative_bool_emit('PyObject_SetItem'),
          priority=0)

# del obj1[obj2]
method_op('__delitem__',
          arg_types=[object_rprimitive, object_rprimitive],
          result_type=bool_rprimitive,
Esempio n. 11
0
    arg_types=[object_rprimitive],
    return_type=list_rprimitive,
    c_function_name='PySequence_List',
    error_kind=ERR_MAGIC,
)

new_list_op = custom_op(
    arg_types=[c_pyssize_t_rprimitive],
    return_type=list_rprimitive,
    c_function_name='PyList_New',
    error_kind=ERR_MAGIC)

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

# 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],
    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(
Esempio n. 12
0
    return_type=c_int_rprimitive,
    c_function_name='CPyDict_UpdateFromAny',
    error_kind=ERR_NEG_INT)

# dict.get(key, default)
c_method_op(
    name='get',
    arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
    return_type=object_rprimitive,
    c_function_name='CPyDict_Get',
    error_kind=ERR_MAGIC)

# dict.get(key)
method_op(
    name='get',
    arg_types=[dict_rprimitive, object_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=simple_emit('{dest} = CPyDict_Get({args[0]}, {args[1]}, Py_None);'))

# Construct an empty dictionary.
dict_new_op = c_custom_op(
    arg_types=[],
    return_type=dict_rprimitive,
    c_function_name='PyDict_New',
    error_kind=ERR_MAGIC)

# Construct a dictionary from keys and values.
# Positional argument is the number of key-value pairs
# Variable arguments are (key1, value1, ..., keyN, valueN).
dict_build_op = c_custom_op(
    arg_types=[c_pyssize_t_rprimitive],
Esempio n. 13
0
    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,
                        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__',
Esempio n. 14
0
               c_function_name=funcname,
               error_kind=ERR_MAGIC,
               priority=0)

c_unary_op(name='not',
           arg_type=object_rprimitive,
           return_type=c_int_rprimitive,
           c_function_name='PyObject_Not',
           error_kind=ERR_NEG_INT,
           truncated_type=bool_rprimitive,
           priority=0)

# obj1[obj2]
method_op(name='__getitem__',
          arg_types=[object_rprimitive, object_rprimitive],
          return_type=object_rprimitive,
          c_function_name='PyObject_GetItem',
          error_kind=ERR_MAGIC,
          priority=0)

# obj1[obj2] = obj3
method_op(name='__setitem__',
          arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
          return_type=c_int_rprimitive,
          c_function_name='PyObject_SetItem',
          error_kind=ERR_NEG_INT,
          priority=0)

# del obj1[obj2]
method_op(name='__delitem__',
          arg_types=[object_rprimitive, object_rprimitive],
          return_type=c_int_rprimitive,
Esempio n. 15
0
                             dict_next_rtuple_single, dict_next_rtuple_pair,
                             c_pyssize_t_rprimitive, c_int_rprimitive,
                             bit_rprimitive)

from mypyc.primitives.registry import (custom_op, method_op, function_op,
                                       binary_op, load_address_op, ERR_NEG_INT)

# Get the 'dict' type object.
load_address_op(name='builtins.dict',
                type=object_rprimitive,
                src='PyDict_Type')

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

# dict[key] = value
dict_set_item_op = method_op(
    name='__setitem__',
    arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
    return_type=c_int_rprimitive,
    c_function_name='CPyDict_SetItem',
    error_kind=ERR_NEG_INT)

# key in dict
binary_op(name='in',
          arg_types=[object_rprimitive, dict_rprimitive],
          return_type=c_int_rprimitive,
Esempio n. 16
0
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]});'))

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_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,
Esempio n. 17
0
"""Primitive tuple ops for *variable-length* tuples.

Note: Varying-length tuples are represented as boxed Python tuple
objects, i.e. tuple_rprimitive (RPrimitive), not RTuple.
"""

from mypyc.ir.ops import ERR_MAGIC
from mypyc.ir.rtypes import (tuple_rprimitive, int_rprimitive, list_rprimitive,
                             object_rprimitive, c_pyssize_t_rprimitive)
from mypyc.primitives.registry import method_op, function_op, custom_op

# tuple[index] (for an int index)
tuple_get_item_op = method_op(name='__getitem__',
                              arg_types=[tuple_rprimitive, int_rprimitive],
                              return_type=object_rprimitive,
                              c_function_name='CPySequenceTuple_GetItem',
                              error_kind=ERR_MAGIC)

# Construct a boxed tuple from items: (item1, item2, ...)
new_tuple_op = custom_op(arg_types=[c_pyssize_t_rprimitive],
                         return_type=tuple_rprimitive,
                         c_function_name='PyTuple_Pack',
                         error_kind=ERR_MAGIC,
                         var_arg_type=object_rprimitive)

# Construct tuple from a list.
list_tuple_op = function_op(name='builtins.tuple',
                            arg_types=[list_rprimitive],
                            return_type=tuple_rprimitive,
                            c_function_name='PyList_AsTuple',
                            error_kind=ERR_MAGIC,
Esempio n. 18
0
          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)

# 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);'),
                   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,
Esempio n. 19
0
            return_type=dict_rprimitive,
            c_function_name='PyDict_Copy',
            error_kind=ERR_MAGIC,
            priority=2)

# Generic one-argument dict constructor: dict(obj)
function_op(name='builtins.dict',
            arg_types=[object_rprimitive],
            return_type=dict_rprimitive,
            c_function_name='CPyDict_FromAny',
            error_kind=ERR_MAGIC)

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

# dict[key] = value
dict_set_item_op = method_op(
    name='__setitem__',
    arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
    return_type=c_int_rprimitive,
    c_function_name='CPyDict_SetItem',
    error_kind=ERR_NEG_INT)

# key in dict
binary_op(name='in',
          arg_types=[object_rprimitive, dict_rprimitive],
          return_type=c_int_rprimitive,
Esempio n. 20
0
    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,
                           emit=call_negative_bool_emit('PyList_Append'))

# list.extend(obj)
list_extend_op = method_op(name='extend',
                           arg_types=[list_rprimitive, object_rprimitive],
                           result_type=object_rprimitive,
                           error_kind=ERR_MAGIC,
                           emit=call_emit('CPyList_Extend'))

# list.pop()
list_pop_last = c_method_op(name='pop',
                            arg_types=[list_rprimitive],
                            return_type=object_rprimitive,
                            c_function_name='CPyList_PopLast',