def return_transformer(node, resources):
    _validate_restrictions(node)
    rtseq = resources.get_rtseq()
    expression = utils.generic_ast_node_transform(node.value, resources)
    stripped_expression = expression[:expression.find("[")] if expression.find(
        "[") != -1 else expression
    if isinstance(node.value, (ast.Name, ast.Attribute, ast.Subscript)):
        src_var_name = utils.get_variable_name_from_node(node.value)
        if resources.has_variable(
                str(src_var_name
                    )) and not resources.has_channel_ref(stripped_expression):
            rt_expression = expression
            return_default_value = resources.get_variable_py_value(
                src_var_name)
            # In case of "return var[0]" the default value is saved as a list, so make sure to not return list type
            # because those cannot be return variables.
            # The len check is there to not get index error in case of empty lists -> for that I don't know yet
            # what the solution is, so I will leave it like this (Arnold)
            if isinstance(return_default_value, ArrayType):
                if len(return_default_value.value):
                    return_default_value = return_default_value[0]
        else:
            raise TranslateError(_errormessages.invalid_return_value)
    elif isinstance(node.value, (ast.Num, ast.Call)):
        return_default_value = utils.get_value_from_node(node.value, resources)
        if isinstance(return_default_value, ArrayType):
            raise TranslateError(_errormessages.invalid_return_type)
        rt_expression = expression
    else:
        raise TranslateError(_errormessages.invalid_return_value)
    var_name = rtseqapi.add_return_variable(rtseq, '__ret_var__',
                                            return_default_value)
    rtseqapi.add_assignment(resources.get_current_block(), var_name,
                            rt_expression)
    return "return " + str(expression)
def _decorator_to_arg(node, resources):
    arg_name = def_value = by_value = None
    if not len(node.args) == 3:
        raise errors.TranslateError(_errormessages.invalid_param_decorator)
    # this is a decorator param definition. First parameter is the string for the name.
    if utils.is_node_ast_str(node.args[0]):
        arg_name = utils.get_value_from_str_node(node.args[0])
    # second is the default value
    try:
        def_value = utils.get_value_from_node(node.args[1], resources)
    except errors.TranslateError:
        # def_value won't get assigned anything if an error occurs, which will trigger the exception later.
        pass
    # third is whether to pass by ref or by value
    valid_types = [ast.Name, ast.Attribute]
    if isinstance(node.args[2], tuple(valid_types)):
        by_value_str = utils.get_variable_name_from_node(node.args[2])
        by_value_str = getattr(_decorators.NivsParam,
                               by_value_str.split('.')[-1], by_value_str)
        by_value = BooleanValue(by_value_str).value
    elif 'NameConstant' in dir(ast) and utils.is_node_ast_nameconstant(
            node.args[2]):
        by_value = utils.get_value_from_nameconstant_node(node.args[2])

    if arg_name is None or def_value is None or by_value is None:
        raise errors.TranslateError(_errormessages.invalid_param_decorator)
    return _param(arg_name, def_value, by_value)
def raise_if_invalid_invert_operand(node, resources):
    invalid_operand = False
    try:
        if isinstance(utils.get_value_from_node(node, resources).value, (bool, float)):
            invalid_operand = True
    except errors.TranslateError:
        pass
    if invalid_operand:
        raise errors.TranslateError(_errormessages.invalid_operand_for_unary_invert_operator)
def raise_if_invalid_bool_operand(node, resources):
    invalid_operand = False
    try:
        if not isinstance(utils.get_value_from_node(node, resources).value, bool):
            invalid_operand = True
    except errors.TranslateError:
        pass
    if invalid_operand:
        raise errors.TranslateError(_errormessages.invalid_operand_for_boolean_operator)
Esempio n. 5
0
def assign_transformer(node, resources):
    node_value = None
    initial_channel_ref_declaration = False
    lhs = node.targets[0]
    rtseq_var_name = utils.generic_ast_node_transform(lhs, resources)
    # the left hand side can only be a variable name or a name with an attribute (var.value)
    if isinstance(lhs, ast.Name):
        variable_name = utils.get_variable_name_from_node(lhs)
        # if the variable already exists this kind of assignment is invalid, use var.value instead
        if resources.has_variable(variable_name):
            raise TranslateError(_errormessages.variable_reassignment)
    elif isinstance(lhs, ast.Attribute):
        # in case of var[0].value get rid of the [0] part and search in the dictionary for var
        stripped_rtseq_var_name = rtseq_var_name[:rtseq_var_name.find("[")] if rtseq_var_name.find("[") != -1 \
            else rtseq_var_name
        variable_name = resources.get_variable_py_name(stripped_rtseq_var_name)
    else:
        raise TranslateError(_errormessages.variable_reassignment)
    rtseq = resources.get_rtseq()
    block = resources.get_current_block()
    if not resources.has_variable(variable_name):
        # new local variable
        node_value = utils.get_value_from_node(node.value, resources)
        if isinstance(
                node_value,
            (_datatypes.ChannelReference, _datatypes.VectorChannelReference)):
            initial_channel_ref_declaration = True
            channel_name = utils.get_channel_name(node.value.args[0])
            rtseq_var_name = rtseqapi.to_channel_ref_name(variable_name)
            resources.add_channel_ref(
                variable_name, channel_name, rtseq_var_name,
                isinstance(node_value, _datatypes.ArrayType))
        elif isinstance(node_value, _datatypes.DataType):
            rtseq_var_name = rtseqapi.add_local_variable(
                rtseq, variable_name, node_value)
            # add the local variable's accessor to the resources
            resources.add_variable(variable_name, node_value, rtseq_var_name)
            resources.add_variable(variable_name + ".value", node_value,
                                   rtseq_var_name)
        else:
            raise TranslateError(_errormessages.init_var_invalid_type)
    transformed_node_value = utils.generic_ast_node_transform(
        node.value, resources)
    rtseq_var_name = resources.get_variable_rtseq_name(
        variable_name) if not rtseq_var_name else rtseq_var_name
    if not initial_channel_ref_declaration:
        if isinstance(node_value, _datatypes.ArrayType):
            if transformed_node_value.count(',') > 0:
                value_list = transformed_node_value.split(',')
                for index, val in enumerate(value_list):
                    rtseqapi.add_assignment(
                        block, rtseq_var_name + "[" + str(index) + "]", val)
        else:
            rtseqapi.add_assignment(block, rtseq_var_name,
                                    transformed_node_value)
def raise_if_negative_binary_operator_operand(node, resources):
    invalid_operand = False
    if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
        invalid_operand = True
    else:
        try:
            value = utils.get_value_from_node(node, resources).value
            if value < 0:
                invalid_operand = True
        except errors.TranslateError:
            pass
    if invalid_operand:
        raise errors.TranslateError(_errormessages.negative_operand_for_binary_operator)
Esempio n. 7
0
def attribute_transformer(node, resources):
    var_name = utils.get_variable_name_from_node(node)
    if resources.has_variable(var_name):
        if isinstance(node.value, ast.Subscript):
            return utils.generic_ast_node_transform(node.value, resources)
        else:
            return resources.get_variable_rtseq_name(var_name)
    try:
        # Try to get the value of the node in case it's a DataType(x).value style.
        node_value = utils.get_value_from_node(node.value, resources)
        return str(node_value)
    except errors.TranslateError:
        # If we get a TranslateError it's because it wasn't a DataType(x).value, so move on.
        pass
    built_exp = utils.generic_ast_node_transform(node.value,
                                                 resources) + '.' + node.attr
    if built_exp in symbols._symbols:
        return symbols._symbols[built_exp]
    else:
        raise errors.TranslateError(_errormessages.unknown_identifier %
                                    var_name)