def custom_op(arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, name: Optional[str] = None, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, is_var_arg: bool = False) -> OpDescription: """ Create a one-off op that can't be automatically generated from the AST. Note that if the format_str argument is not provided, then a format_str is generated using the name argument. The name argument only needs to be provided if the format_str argument is not provided. """ if name is not None and format_str is None: typename = '' if len(arg_types) == 1: typename = ' :: %s' % short_name(arg_types[0].name) format_str = '{dest} = %s %s%s' % (short_name(name), ', '.join( '{args[%d]}' % i for i in range(len(arg_types))), typename) assert format_str is not None return OpDescription('<custom>', arg_types, result_type, is_var_arg, error_kind, format_str, emit, steals, is_borrowed, 0)
def custom_op(arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, name: Optional[str] = None, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, is_var_arg: bool = False, priority: int = 1) -> OpDescription: """Create a one-off op that can't be automatically generated from the AST. Note that if the format_str argument is not provided, then a format_str is generated using the name argument. The name argument only needs to be provided if the format_str argument is not provided. Most arguments are similar to func_op(). If is_var_arg is True, the op takes an arbitrary number of positional arguments. arg_types should contain a single type, which is used for all arguments. """ if name is not None and format_str is None: typename = '' if len(arg_types) == 1: typename = ' :: %s' % short_name(arg_types[0].name) format_str = '{dest} = %s %s%s' % (short_name(name), ', '.join( '{args[%d]}' % i for i in range(len(arg_types))), typename) assert format_str is not None return OpDescription('<custom>', arg_types, result_type, is_var_arg, error_kind, format_str, emit, steals, is_borrowed, priority)
def method_op(name: str, arg_types: List[RType], result_type: Optional[RType], error_kind: int, emit: EmitCallback, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> OpDescription: """Define a primitive op that replaces a method call. Most arguments are similar to func_op(). This will be automatically generated by matching against the AST. Args: name: short name of the method (for example, 'append') arg_types: argument types; the receiver is always the first argument result_type: type of the result, None if void """ ops = method_ops.setdefault(name, []) assert len(arg_types) > 0 args = ', '.join('{args[%d]}' % i for i in range(1, len(arg_types))) type_name = short_name(arg_types[0].name) if name == '__getitem__': format_str = '{dest} = {args[0]}[{args[1]}] :: %s' % type_name else: format_str = '{dest} = {args[0]}.%s(%s) :: %s' % (name, args, type_name) desc = OpDescription(name, arg_types, result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc) return desc
def unary_op(op: str, arg_type: RType, result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> OpDescription: ops = unary_ops.setdefault(op, []) if format_str is None: format_str = '{dest} = %s{args[0]}' % op desc = OpDescription(op, [arg_type], result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc) return desc
def binary_op(op: str, arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> None: assert len(arg_types) == 2 ops = binary_ops.setdefault(op, []) if format_str is None: format_str = '{dest} = {args[0]} %s {args[1]}' % op desc = OpDescription(op, arg_types, result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc)
def name_ref_op(name: str, result_type: RType, error_kind: int, emit: EmitCallback, is_borrowed: bool = False) -> OpDescription: """Define an op that is used to implement reading a module attribute. Args: name: fully-qualified name (e.g. 'builtins.None') """ assert name not in name_ref_ops, 'already defined: %s' % name format_str = '{dest} = %s' % short_name(name) desc = OpDescription(name, [], result_type, False, error_kind, format_str, emit, False, is_borrowed, 0) name_ref_ops[name] = desc return desc
def name_ref_op(name: str, result_type: RType, error_kind: int, emit: EmitCallback, is_borrowed: bool = False) -> OpDescription: """Define an op that is used to implement reading a module attribute. This will be automatically generated by matching against the AST. Most arguments are similar to func_op(). Args: name: fully-qualified name (e.g. 'builtins.None') """ assert name not in name_ref_ops, 'already defined: %s' % name format_str = '{dest} = %s' % short_name(name) desc = OpDescription(name, [], result_type, False, error_kind, format_str, emit, False, is_borrowed, 0) name_ref_ops[name] = desc return desc
def func_op(name: str, arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> OpDescription: ops = func_ops.setdefault(name, []) typename = '' if len(arg_types) == 1: typename = ' :: %s' % short_name(arg_types[0].name) if format_str is None: format_str = '{dest} = %s %s%s' % (short_name(name), ', '.join( '{args[%d]}' % i for i in range(len(arg_types))), typename) desc = OpDescription(name, arg_types, result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc) return desc
def func_op(name: str, arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> OpDescription: """Define a PrimitiveOp that implements a Python function call. This will be automatically generated by matching against the AST. Args: name: full name of the function arg_types: positional argument types for which this applies result_type: type of the return value error_kind: how errors are represented in the result (one of ERR_*) emit: called to construct C code for the op format_str: used to format the op in pretty-printed IR (if None, use default formatting) steals: description of arguments that this steals (ref count wise) is_borrowed: if True, returned value is borrowed (no need to decrease refcount) priority: if multiple ops match, the one with the highest priority is picked """ ops = func_ops.setdefault(name, []) typename = '' if len(arg_types) == 1: typename = ' :: %s' % short_name(arg_types[0].name) if format_str is None: format_str = '{dest} = %s %s%s' % (short_name(name), ', '.join('{args[%d]}' % i for i in range(len(arg_types))), typename) desc = OpDescription(name, arg_types, result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc) return desc
def unary_op(op: str, arg_type: RType, result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> OpDescription: """Define a PrimitiveOp for a unary operation. Arguments are similar to func_op(), but only a single argument type is expected. This will be automatically generated by matching against the AST. """ ops = unary_ops.setdefault(op, []) if format_str is None: format_str = '{dest} = %s{args[0]}' % op desc = OpDescription(op, [arg_type], result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc) return desc
def binary_op(op: str, arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1) -> None: """Define a PrimitiveOp for a binary operation. Arguments are similar to func_op(), but exactly two argument types are expected. This will be automatically generated by matching against the AST. """ assert len(arg_types) == 2 ops = binary_ops.setdefault(op, []) if format_str is None: format_str = '{dest} = {args[0]} %s {args[1]}' % op desc = OpDescription(op, arg_types, result_type, False, error_kind, format_str, emit, steals, is_borrowed, priority) ops.append(desc)