Esempio n. 1
0
 def veval_with_default(nast, default_value):
     if nast is None:
         ret = values.NumberValue(default_value)
         ret.name = '@SliceDefault'
         return ret
     obj = veval_ast(astc.c(nast), local_field, graph)
     return try_get_value(obj, 'subscript', lineprop)
Esempio n. 2
0
def generate_value_with_type(value: 'values.Value', type_,  suffix_type = SuffixType.Unknown):
    assert(isinstance(value, values.Value))
    ret = None
    if isinstance(value, values.TensorValue):
        ret = values.TensorValue()
        ret.shape = value.shape
        ret.dtype = type_

    elif isinstance(value, values.NumberValue):
        ret = values.NumberValue(None)
        ret.dtype = type_

    else:
        assert(False)

    if suffix_type == SuffixType.Unknown:
        ret.name = value.name + '_st'
    elif suffix_type == SuffixType.Unused:
        ret.name = value.name + '_unused'
    elif suffix_type == SuffixType.Dummy:
        ret.name = value.name + '_dummy'
    elif suffix_type == SuffixType.Input:
        ret.name = value.name + '_in'
    else:
        assert(False)

    return ret
Esempio n. 3
0
    def vcall(self,
              module: 'values.Field',
              graph: 'graphs.Graph',
              inst: 'values.Object',
              args: 'functions.FunctionArgInput',
              context: 'functions.VEvalContext' = None,
              line=-1):

        if context._for_unroll:
            for ref in args.inputs:
                if not ref.get_value().has_constant_value():
                    assert False, 'Loop unrolling was requested for non-constant sequence at %s' % line

            refs = []
            for num in range(*(ref.get_value().internal_value
                               for ref in args.inputs)):
                refs.append(values.Object(values.NumberValue(num)))

            value = values.ListValue(refs)
            return values.Object(value)
        else:
            node = nodes.NodeGenerate('range',
                                      [v.get_value() for v in args.inputs],
                                      line)
            graph.add_node(node)
            value = values.RangeValue()
            value.name = '@F.{}.{}'.format(line, self.name)
            node.set_outputs([value])
            return values.Object(value)
    def __init__(self):
        super().__init__()
        self.name = 'array'

        self.args.add_arg('object', values.NoneValue())
        self.args.add_arg('dtype', values.NoneValue())
        self.args.add_arg('copy', values.BoolValue(True))
        self.args.add_arg('order', values.StrValue('K'))
        self.args.add_arg('subok', values.BoolValue(False))
        self.args.add_arg('ndmin', values.NumberValue(0))
Esempio n. 5
0
 def vcall(self, module: 'Field', graph: 'Graph', inst: 'values.ValueRef', args: 'functions.FunctionArgInput', line=-1):
     node = nodes.NodeLen(
         args.inputs[0].get_value(),  # TODO: Check this.
         line
     )
     graph.add_node(node)
     value = values.NumberValue(None)
     value.name = '@F.{}.{}'.format(line, self.name)
     node.set_outputs([value])
     return values.ValueRef(value)
def veval(op: 'nodes.UnaryOpType', value: 'values.Value'):

    if isinstance(value, values.NumberValue):
        if value.internal_value is not None:
            if op == nodes.UnaryOpType.UAdd:
                return values.NumberValue(value.internal_value)
            if op == nodes.UnaryOpType.USub:
                return values.NumberValue(-value.internal_value)
            else:
                return functions.generate_value_with_same_type(value)
        else:
            return functions.generate_value_with_same_type(value)

    if isinstance(value, values.BoolValue):
        return functions.generate_value_with_same_type(value)

    if op == nodes.UnaryOpType.Not and isinstance(value, values.ListValue):
        return values.BoolValue(None)

    return values.Value()
Esempio n. 7
0
def generate_copied_value(value: 'values.Value'):
    assert(isinstance(value, values.Value))

    if isinstance(value, values.NumberValue):
        copied = values.NumberValue(value.internal_value)
        copied.dtype = value.dtype
        return copied

    if isinstance(value, values.TensorValue):
        copied = values.TensorValue()
        copied.value = value.value
        copied.shape = value.shape
        copied.dtype = value.dtype
        return copied

    if isinstance(value, values.ListValue):
        copied = values.ListValue()
        copied.dtype = value.dtype
        copied.vtype = value.vtype
        if value.internal_value is not None:
            copied.internal_value = value.internal_value.copy()
        return copied

    if isinstance(value, values.NoneValue):
        copied = values.NoneValue()
        return copied

    if isinstance(value, values.BoolValue):
        copied = values.BoolValue(value.internal_value)
        return copied

    if isinstance(value, values.StrValue):
        copied = values.StrValue(value.internal_value)
        return copied

    if isinstance(value, values.RangeValue):
        copied = values.RangeValue()
        return copied

    if isinstance(value, values.TupleValue):
        if value.internal_value is not None:
            copied = values.TupleValue(value.internal_value.copy())
        else:
            copied = values.TupleValue(value.internal_value)
        copied.dtype = value.dtype
        copied.vtype = value.vtype
        return copied

    if config.show_warnings:
        print('Unknown type {} is copied'.format(value))

    return values.Value()
Esempio n. 8
0
def veval_ast_num(astc: 'AstContext', local_field: 'values.Field',
                  graph: 'Graph'):
    '''
    Ex. 1, 2, ...
    '''
    assert (isinstance(astc.nast, gast.gast.Num))
    lineprop = utils.LineProperty(astc.lineno, astc.filename)
    value = values.NumberValue(astc.nast.n)
    ret = values.ValueRef(value)

    name = values.create_ref_value_name_with_constant(ret)
    ret.name = name
    ret.get_value().name = name
    return ret
Esempio n. 9
0
def veval(op: 'nodes.BinOpType', left: 'values.Value', right: 'values.Value',
          lineprop: 'utils.LineProperty'):

    initialize_lazy()

    if isinstance(left, values.ListValue):
        return functions.generate_value_with_same_type(left)

    if isinstance(left, values.TupleValue):
        return functions.generate_value_with_same_type(left)

    if isinstance(right, values.NumberValue) or isinstance(
            right, values.TensorValue):

        if not isinstance(left, values.NumberValue) and not isinstance(
                left, values.TensorValue):
            utils.print_warning('Unestimated type is on left', lineprop)
            left = values.NumberValue(0.0)

        left_type = left.dtype
        right_type = right.dtype

        if not config.float_restrict:
            if left_type == utils.dtype_float64:
                left_type = utils.dtype_float32
            if right_type == utils.dtype_float64:
                right_type = utils.dtype_float32

        if left_type is None:
            left_type = np.array(0.0, np.float32).dtype

        if right_type is None:
            right_type = np.array(0.0, np.float32).dtype

        result_type = None

        for v in binop_type_table:
            if v[0] == op and v[1] == left_type and v[2] == right_type:
                result_type = v[3]
                break

        assert (result_type is not None)

        if isinstance(right, values.TensorValue):
            return functions.generate_value_with_type(right, type_=result_type)
        else:
            return functions.generate_value_with_type(left, type_=result_type)

    return values.Value()
    def vcall(self,
              module: 'Field',
              graph: 'Graph',
              inst: 'values.ValueRef',
              args: 'functions.FunctionArgInput',
              line=-1):
        args = functions.FunctionArgInput()
        args.inputs.append(inst)
        args.keywords['self'] = inst

        node = nodes.NodeCall(self, args, line)

        value = values.NumberValue(None)
        value.dtype = np.array(0).dtype
        value.name = '@F.{}.{}'.format(line, self.name)
        node.set_outputs([value])

        graph.add_node(node)
        return values.ValueRef(value)
Esempio n. 11
0
    def vcall(self,
              module: 'values.Field',
              graph: 'graphs.Graph',
              inst: 'values.Object',
              args: 'functions.FunctionArgInput',
              context: 'functions.VEvalContext' = None,
              line=-1):
        node = nodes.NodeCall(self, args, line)
        graph.add_node(node)
        item = args.get_value().inputs[0]
        default_value = None
        # constant propagation whenever possible
        if item.has_constant_value():
            default_value = len(item.internal_value)

        value = values.NumberValue(default_value)
        value.name = '@F.{}.{}'.format(line, self.name)
        node.set_outputs([value])
        return values.Object(value)
    def vcall(self,
              module: 'values.Field',
              graph: 'graphs.Graph',
              inst: 'values.Object',
              args: 'functions.FunctionArgInput',
              context: 'functions.VEvalContext' = None,
              line=-1):
        funcArgs = self.args.merge_inputs(inst, args)

        node = nodes.NodeCall(self, funcArgs, line)
        graph.add_node(node)

        axis = funcArgs.keywords['axis']
        if isinstance(axis, values.NoneValue):
            value = values.NumberValue(None)
            value.dtype = np.int64
        else:
            value = values.TensorValue()
            value.dtype = np.int64

        value.name = '@F.{}.{}'.format(line, self.name)
        node.set_outputs([value])
        return values.Object(value)
Esempio n. 13
0
def generate_value_with_same_type(value: 'values.Value', is_dummy_value = False, suffix_type = SuffixType.Unknown):
    assert(isinstance(value, values.Value))
    ret = None
    if isinstance(value, values.TensorValue):
        ret = values.TensorValue()
        ret.shape = value.shape
        ret.dtype = value.dtype

    elif isinstance(value, values.NumberValue):
        dtype = None
        if value.internal_value is None:
            dtype = value.dtype
        elif isinstance(value.internal_value, int):
            dtype = np.array(value.internal_value).dtype
        elif isinstance(value.internal_value, float):
            dtype = np.array(value.internal_value).dtype

        ret = values.NumberValue(None)
        ret.dtype = dtype

    elif isinstance(value, values.StrValue):
        ret = values.StrValue(None)

    elif isinstance(value, values.BoolValue):
        ret = values.BoolValue(None)

    elif isinstance(value, values.ListValue):
        ret = values.ListValue(None)
        ret.dtype = value.dtype
        ret.vtype = value.vtype

    elif isinstance(value, values.NoneValue):
        ret = values.NoneValue()

    elif isinstance(value, values.TupleValue):
        ret = values.TupleValue()
        ret.dtype = value.dtype
        ret.vtype = value.vtype

    elif isinstance(value, values.RangeValue):
        ret = values.RangeValue()

    elif isinstance(value, values.UnknownValue):
        ret = values.UnknownValue()

    elif ret is None and isinstance(value, values.Value):
        ret = values.Value()

    else:
        assert(False)

    assert(ret is not None)

    ret.is_dummy_value = is_dummy_value
    if suffix_type == SuffixType.Unknown:
        ret.name = value.name + '_st'
    elif suffix_type == SuffixType.Unused:
        ret.name = value.name + '_unused'
    elif suffix_type == SuffixType.Dummy:
        ret.name = value.name + '_dummy'
    elif suffix_type == SuffixType.Input:
        ret.name = value.name + '_in'
    else:
        assert(False)

    return ret
Esempio n. 14
0
def veval_ast_listcomp(astc: 'AstContext', local_field: 'values.Field',
                       graph: 'Graph'):
    '''
    Ex. [x for x in xx]
    [elt for target in iter]
    '''
    assert (isinstance(astc.nast, gast.gast.ListComp))
    lineprop = utils.LineProperty(astc.lineno, astc.filename)

    listcomp_guid = str(utils.get_guid())
    listcomp_id = 'listcomp_' + listcomp_guid
    body_id = 'listcomp_body_' + listcomp_guid
    internal_counter_id = '@internal/listcomp_counter_' + listcomp_guid
    internal_list_id = '@internal/listcomp_list_' + listcomp_guid
    internal_cond_id = '@internal/listcomp_cond_' + listcomp_guid

    generator = astc.nast.generators[0]
    iter_value = try_get_value(
        veval_ast(astc.c(generator.iter), local_field, graph), 'generator',
        lineprop)
    list_value = values.ListValue()
    list_obj = values.ValueRef(list_value)

    node_generate_list = nodes.NodeGenerate('List', [], lineprop)
    node_generate_list.set_outputs([list_value])
    graph.add_node(node_generate_list)

    # body
    target_name = ''
    if isinstance(generator.target, gast.gast.Name):
        target_name = generator.target.id
    else:
        if config.show_warnings:
            print('This for is not supported. in L.{}'.format(astc.lineno))
        return None

    counter_value = values.NumberValue(None)
    counter_value.dtype = np.array(0).dtype
    counter_value.name = internal_counter_id

    cond_value = values.BoolValue(None)
    cond_value.name = internal_cond_id

    # set values with internal name
    local_field.get_attribute(internal_list_id).revise(list_obj)

    values.push_history(listcomp_id)

    body_graph = Graph()
    body_graph.root_graph = graph.root_graph
    body_graph.name = 'Body_' + listcomp_guid

    node_forgen = nodes.NodeForGenerator(counter_value, iter_value)

    target_ref = iter_value.get_iterator()
    if target_ref is None:
        target_ref = values.ValueRef(values.UnknownValue())
        if config.show_warnings:
            print('unknown iteratable type in L.{}'.format(lineprop))
    target_value = target_ref.get_value()

    node_forgen.set_outputs([target_ref.get_value()])
    local_field.get_attribute(target_name).revise(target_ref)

    body_graph.add_node(node_forgen)

    elt = veval_ast(astc.c(astc.nast.elt), local_field, body_graph)
    elt_obj = try_get_ref(elt, 'listcomp', lineprop)

    finput = functions.FunctionArgInput()
    finput.inputs.append(elt_obj)

    append_value = local_field.get_attribute(internal_list_id).get_ref(
    ).get_field().get_attribute('append').get_ref().get_value()
    append_value.func.vcall(
        None, body_graph,
        local_field.get_attribute(internal_list_id).get_ref(), finput,
        lineprop)

    value_inputs = values.get_inputs()
    value_outputs = values.get_outputs()

    values.pop_history()

    inputs = []
    outputs = []

    # default input for subgraph's input
    body_graph.add_input_value(counter_value)
    body_graph.add_input_value(cond_value)
    body_graph.add_input_value(iter_value)

    # default output for subgraph's output
    body_graph.add_output_value(cond_value)
    body_graph.add_output_value(iter_value)

    # default output
    outputs.append(functions.generate_value_with_same_type(iter_value))

    # generate pairs
    value_pairs = {}
    for v in value_inputs:
        key = str(v.field.id) + '_' + v.name
        if not (key in value_pairs.keys()):
            value_pairs[key] = {}

        value_pairs[key]['field'] = v.field
        value_pairs[key]['name'] = v.name
        value_pairs[key]['input_value'] = v.input_value
        value_pairs[key]['input_body_value'] = v.value

    for v in value_outputs:
        key = str(v.field.id) + '_' + v.name
        if not (key in value_pairs.keys()):
            value_pairs[key] = {}

        value_pairs[key]['field'] = v.field
        value_pairs[key]['name'] = v.name
        value_pairs[key]['output_body_value'] = v.value
        value_pairs[key]['output_obj'] = v.obj

    # remove iterator
    removed_name = str(local_field.id) + '_' + target_value.name
    del value_pairs[removed_name]

    for k, v in value_pairs.items():
        name = v['name']
        field = v['field']

        if 'input_body_value' in v:
            inputs.append(v['input_value'])
            body_graph.add_input_value(v['input_body_value'])

        else:
            temp_value1 = functions.generate_value_with_same_type(
                v['output_body_value'])
            temp_value2 = functions.generate_value_with_same_type(
                v['output_body_value'])
            inputs.append(temp_value1)
            body_graph.add_input_value(temp_value2)

        if 'output_body_value' in v:
            body_graph.add_output_value(v['output_body_value'])
            output_value = functions.generate_value_with_same_type(
                v['output_body_value'])
            outputs.append(output_value)
            if 'output_obj' in v:
                obj = v['output_obj']
                obj.revise(output_value)
                field.get_attribute(name).revise(obj)
            elif field.get_attribute(name).has_obj():
                field.get_attribute(name).get_ref().revise(output_value)
            else:
                field.get_attribute(name).revise(values.ValueRef(output_value))
        else:
            temp_value1 = v['input_body_value']
            temp_value2 = functions.generate_value_with_same_type(
                v['input_body_value'])
            body_graph.add_output_value(temp_value1)
            outputs.append(temp_value2)

    node = nodes.NodeListcomp(iter_value, inputs, body_graph, astc.lineno)
    node.set_outputs(outputs)

    graph.add_node(node)

    return local_field.get_attribute(internal_list_id).get_ref()
Esempio n. 15
0
def veval_ast_for(astc: 'AstContext', local_field: 'values.Field',
                  graph: 'Graph'):
    '''
    for target in iter:
        ...
    '''
    assert (isinstance(astc.nast, gast.gast.For))
    lineprop = utils.LineProperty(astc.lineno, astc.filename)

    # for target in iter:
    iter_ = veval_ast(astc.c(astc.nast.iter), local_field, graph)
    input_iter_value = try_get_value(iter_, 'for', lineprop)
    body_iter_value = functions.generate_value_with_same_type(
        input_iter_value, suffix_type=functions.SuffixType.Input)

    # get target name
    target_name = ''
    if isinstance(astc.nast.target, gast.gast.Name):
        target_name = astc.nast.target.id
    else:
        if config.show_warnings:
            print('This for is not supported. in L.{}'.format(astc.lineno))
        return None

    # unroll?
    if isinstance(input_iter_value,
                  values.ListValue) and input_iter_value.has_constant_value(
                  ) and input_iter_value.dtype is None:
        return veval_ast_for_unroll(astc, target_name, input_iter_value,
                                    local_field, graph)

    for_guid = utils.get_guid()
    for_id = 'for_' + str(for_guid)
    body_id = 'body_' + str(for_guid)

    values.push_history(for_id)

    # body
    body_graph = Graph()
    body_graph.root_graph = graph.root_graph
    body_graph.name = 'Body_' + str(for_guid)

    # generate a node for input
    node_input = nodes.NodeInput('input')
    body_graph.add_node(node_input)

    body_counter_value = values.NumberValue(None)
    body_counter_value.dtype = np.array(0).dtype
    body_counter_value.name = 'for_counter_' + str(for_guid)

    body_cond_value = values.BoolValue(None)
    body_cond_value.name = 'for_cond_' + str(for_guid)

    # create a node to lookup a value from sequence
    node_forgen = nodes.NodeForGenerator(body_counter_value, body_iter_value)

    # generate iterator
    target_ref = input_iter_value.get_iterator()
    if target_ref is None:
        target_ref = values.ValueRef(values.UnknownValue())
        if config.show_warnings:
            print('unknown iteratable type in L.{}'.format(astc.lineno))
    target_value = target_ref.get_value()

    node_forgen.set_outputs([target_ref.get_value()])

    target_attribute = local_field.get_attribute(target_name)
    target_attribute.revise(target_ref)
    body_graph.add_node(node_forgen)

    # veval body
    body = veval_ast(astc.c(astc.nast.body), local_field, body_graph)

    value_inputs = values.get_inputs()
    value_outputs = values.get_outputs()

    break_attribute = local_field.get_attribute('#keepgoing')
    if break_attribute.has_obj():
        break_attribute_ref = break_attribute.get_ref()
        break_attribute_value = break_attribute_ref.get_value()
    else:
        break_attribute_value = body_cond_value

    values.pop_history()

    inputs = []
    outputs = []
    node_input_outputs = []

    # default input for subgraph's input
    body_graph.add_input_value(body_counter_value)
    body_graph.add_input_value(body_cond_value)
    body_graph.add_input_value(body_iter_value)

    # default output for subgraph's output
    body_graph.add_output_value(break_attribute_value)
    body_graph.add_output_value(body_iter_value)

    # default output
    outputs.append(functions.generate_value_with_same_type(input_iter_value))

    # generate pairs
    value_pairs = {}
    for v in value_inputs:
        key = str(v.field.id) + '_' + v.name
        if not (key in value_pairs.keys()):
            value_pairs[key] = {}

        value_pairs[key]['field'] = v.field
        value_pairs[key]['name'] = v.name
        value_pairs[key]['input_value'] = v.input_value
        value_pairs[key]['input_body_value'] = v.value

    for v in value_outputs:
        key = str(v.field.id) + '_' + v.name
        if not (key in value_pairs.keys()):
            value_pairs[key] = {}

        value_pairs[key]['field'] = v.field
        value_pairs[key]['name'] = v.name
        value_pairs[key]['output_body_value'] = v.value
        value_pairs[key]['output_obj'] = v.obj

    for k, v in value_pairs.items():
        name = v['name']
        field = v['field']

        if 'input_body_value' in v:
            inputs.append(v['input_value'])

            body_graph.add_input_value(v['input_body_value'])
        else:
            temp_value1 = functions.generate_value_with_same_type(
                v['output_body_value'],
                is_dummy_value=True,
                suffix_type=functions.SuffixType.Dummy)
            temp_value2 = functions.generate_value_with_same_type(
                v['output_body_value'], suffix_type=functions.SuffixType.Dummy)
            inputs.append(temp_value1)

            body_graph.add_input_value(temp_value2)
            node_input_outputs.append(temp_value2)

        if 'output_body_value' in v:
            body_graph.add_output_value(v['output_body_value'])
            output_value = functions.generate_value_with_same_type(
                v['output_body_value'])
            outputs.append(output_value)

            if 'output_obj' in v:
                obj = v['output_obj']
                obj.revise(output_value)
                field.get_attribute(name).revise(obj)
            elif field.get_attribute(name).has_obj():
                field.get_attribute(name).get_ref().revise(output_value)
            else:
                field.get_attribute(name).revise(values.ValueRef(output_value))
        else:
            temp_value1 = v['input_body_value']
            temp_value2 = functions.generate_value_with_same_type(
                v['input_body_value'])
            body_graph.add_output_value(temp_value1)
            outputs.append(temp_value2)

    node = nodes.NodeFor(input_iter_value, inputs, body_graph, body_cond_value,
                         astc.lineno)
    node.set_outputs(outputs)
    node_input.set_outputs(node_input_outputs)

    graph.add_node(node)

    return None
Esempio n. 16
0
def return_NStepLSTM():
    list_tensor = values.ListValue()
    list_tensor.vtype = values.TensorValue
    return [values.TensorValue(), values.TensorValue(), list_tensor]


def return_NStepBiLSTM():
    list_tensor = values.ListValue()
    list_tensor.vtype = values.TensorValue
    return [values.TensorValue(), values.TensorValue(), list_tensor]


chainer_links[chainer.links.Linear] = ChainerLinkDefinition(
    args=[('self', values.NoneValue()), ('x', values.NoneValue()),
          ('n_batch_axes', values.NumberValue(1))],
    estimate_shape=estimate_linear_shape)
chainer_links[chainer.links.Convolution2D] = ChainerLinkDefinition(
    estimate_shape=estimate_convolution2D_shape)
chainer_links[chainer.links.ConvolutionND] = ChainerLinkDefinition(
    estimate_shape=estimate_convolutionND_shape)
chainer_links[chainer.links.BatchNormalization] = ChainerLinkDefinition(
    estimate_shape=estimate_batch_norm_shape)
chainer_links[chainer.links.NStepLSTM] = ChainerLinkDefinition(
    args=[('self', values.NoneValue()), ('hx', values.NoneValue()),
          ('cx', values.NoneValue()), ('xs', values.NoneValue())],
    estimate_shape=estimate_NStepLSTM_shape,
    get_ret=return_NStepLSTM)
chainer_links[chainer.links.NStepBiLSTM] = ChainerLinkDefinition(
    args=[('self', values.NoneValue()), ('hx', values.NoneValue()),
          ('cx', values.NoneValue()), ('xs', values.NoneValue())],
Esempio n. 17
0
def veval(op: 'nodes.BinOpType', left: 'values.Value', right: 'values.Value',
          lineprop: 'utils.LineProperty'):

    initialize_lazy()

    if isinstance(left, values.ListValue):
        return functions.generate_value_with_same_type(left)

    if isinstance(left, values.TupleValue):
        return functions.generate_value_with_same_type(left)

    if isinstance(left, values.StrValue):
        if not (isinstance(right, values.NumberValue) or isinstance(
                right, values.StrValue) or isinstance(right, values.BoolValue)
                or isinstance(right, values.TupleValue)):
            assert False

        if not (left.has_constant_value() or right.has_constant_value()):
            assert False

        if op == nodes.BinOpType.Add:
            if not isinstance(right, values.StrValue):
                assert False
            return values.StrValue(left.internal_value + right.internal_value)

        elif op == nodes.BinOpType.Mod:
            right_internal_value = right.internal_value

            if isinstance(right, values.TupleValue):
                values_ = []
                for ref in right_internal_value:
                    if not (isinstance(ref.get_value(), values.NumberValue)
                            or isinstance(ref.get_value(), values.StrValue)
                            or isinstance(ref.get_value(), values.BoolValue)):
                        assert False
                    if not ref.get_value().has_constant_value():
                        assert False
                    values_.append(ref.get_value())

                right_internal_value = tuple(value.internal_value
                                             for value in values_)
            return values.StrValue(left.internal_value % right_internal_value)

        return values.StrValue("")

    if isinstance(right, values.NumberValue) or isinstance(
            right, values.TensorValue):

        if not isinstance(left, values.NumberValue) and not isinstance(
                left, values.TensorValue):
            utils.print_warning('Unestimated type is on left', lineprop)
            left = values.NumberValue(0.0)

        left_type = left.dtype
        right_type = right.dtype

        if not config.float_restrict:
            if left_type == utils.dtype_float64:
                left_type = utils.dtype_float32
            if right_type == utils.dtype_float64:
                right_type = utils.dtype_float32

        if left_type is None:
            left_type = np.array(0.0, np.float32).dtype

        if right_type is None:
            right_type = np.array(0.0, np.float32).dtype

        result_type = None

        for v in binop_type_table:
            if v[0] == op and v[1] == left_type and v[2] == right_type:
                result_type = v[3]
                break

        assert (result_type is not None)

        if isinstance(right, values.TensorValue):
            return functions.generate_value_with_type(right, type_=result_type)
        else:
            return functions.generate_value_with_type(left, type_=result_type)

    return values.Value()