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 _validate_restrictions(node):
    if validations.check_if_any_in_block(ast.FunctionDef, node.body):
        raise errors.TranslateError(_errormessages.invalid_function_definition)
    if node.returns is not None \
            or len(node.args.kwonlyargs) != 0 \
            or len(node.args.kw_defaults) != 0 \
            or node.args.vararg is not None \
            or node.args.kwarg is not None \
            or len(node.args.defaults) != 0:
        raise errors.TranslateError(_errormessages.invalid_function_definition)
    if validations.check_if_any_in_block(validations.ast_try(), node.body):
        if not isinstance(node.body[0], validations.ast_try()):
            raise errors.TranslateError(_errormessages.try_must_be_first_stmt)
        if len(node.body) > 2:
            raise errors.TranslateError(_errormessages.invalid_stmt_after_try)
        elif len(node.body) == 2:
            if not isinstance(node.body[1], ast.Return):
                raise errors.TranslateError(
                    _errormessages.invalid_stmt_after_try)
    return_statements = [
        statement for statement in node.body
        if isinstance(statement, ast.Return)
    ]
    if len(return_statements) > 1:
        raise errors.TranslateError(_errormessages.multiple_return_statements)
    if validations.check_if_any_in_block(ast.Return, node.body[:-1]):
        raise errors.TranslateError(
            _errormessages.return_unsupported_unless_last)
    for decorator in node.decorator_list:
        decorator_name_node = decorator.func if isinstance(
            decorator, ast.Call) else decorator
        decorator_name = utils.get_variable_name_from_node(decorator_name_node)
        decorator_name = decorator_name.split(".")[-1]
        _raise_if_invalid_decorator(decorator_name)
def for_transformer(node, resources):
    _validate_restrictions(node)
    parent_block = resources.get_current_block()
    var_name = utils.get_variable_name_from_node(node.iter)
    if resources.has_variable(var_name):
        collection_value = resources.get_variable_py_value(var_name)
        if not isinstance(collection_value, ArrayType):
            raise TranslateError(_errormessages.scalar_iterable_collection)
        collection = resources.get_variable_rtseq_name(var_name)
        iterator = node.target.id
        for_statement = rtseqapi.add_foreach_loop(parent_block, iterator,
                                                  collection)
        # add the iterator as local variable, so that attribute_transformer returns the actual rtseq name of
        # the iterator
        resources.add_variable(iterator, 0, iterator)
        resources.add_variable(iterator + ".value", 0, iterator)
    elif utils.generic_ast_node_transform(node.iter,
                                          resources).startswith("range("):
        if len(node.iter.args) > 1:
            raise TranslateError(_errormessages.invalid_range_call)
        max_range = utils.generic_ast_node_transform(node.iter.args[0],
                                                     resources)
        variable = node.target.id
        for_statement = rtseqapi.add_for_loop(parent_block, variable,
                                              max_range)
    else:
        raise TranslateError(_errormessages.invalid_iterable_collection)
    for statement in node.body:
        resources.set_current_block(for_statement.Body)
        utils.generic_ast_node_transform(statement, resources)
    resources.set_current_block(parent_block)
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)
Пример #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)
Пример #6
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)
Пример #7
0
def subscript_transformer(node, resources):
    variable_name = utils.get_variable_name_from_node(node)
    rtseq_var_name = resources.get_variable_rtseq_name(variable_name)
    index = utils.generic_ast_node_transform(node.slice, resources)
    return rtseq_var_name + "[" + index + "]"
Пример #8
0
def _get_name_without_namespace_from_node(node):
    return utils.get_variable_name_from_node(node).split('.')[-1]
Пример #9
0
def raise_if_invalid_if_test(node):
    if isinstance(node, ast.UnaryOp):
        node = node.operand
    if isinstance(node, ast.Call) and utils.get_variable_name_from_node(node.func) in VALID_TYPES:
        raise errors.TranslateError(_errormessages.invalid_type_for_if_test)