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. Args: name: short name of the method (for example, 'append') arg_types: argument typess; 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 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, format_str: str, emit: EmitCallback, is_var_arg: bool = False) -> OpDescription: """Create a one-off op that can't be automatically generated from the AST.""" return OpDescription('<custom>', arg_types, result_type, is_var_arg, error_kind, format_str, emit, 0)
def name_ref_op(name: str, result_type: RType, error_kind: int, emit: EmitCallback) -> 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, 0) name_ref_ops[name] = desc return desc
def unary_op(op: str, arg_type: RType, result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, 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, 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, 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, priority) ops.append(desc)
def func_op(name: str, arg_types: List[RType], result_type: RType, error_kind: int, emit: EmitCallback, format_str: Optional[str] = None, 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, priority) ops.append(desc) return desc