def _attr_lookup(self, attr, value):
        if "__" not in attr:
            return Compare(
                left=Attribute(value=Name(id="self", **self.file),
                               attr=attr,
                               **self.file),
                ops=[Eq()],
                comparators=[self.build_expression(value)],
                **self.file,
            )

        attr, lookup = attr.split("__", 1)

        if lookup == "isnull":
            return Compare(
                left=Attribute(value=Name(id="self", **self.file),
                               attr=attr,
                               **self.file),
                ops=[Is() if value else IsNot()],
                comparators=[
                    Constant(value=None, **self.file)
                    # Name(id="None", **self.file)
                ],
                **self.file,
            )

        if lookup == "exact":
            return self._attr_lookup(attr, value)

        raise ValueError("Unhandled attr lookup")
Example #2
0
 def compBreaker(self, node):
     assert isinstance(node, Compare)
     if len(node.comparators) == 1:
         return node
     else:
         comp1 = Compare(node.left, node.ops[0:1], node.comparators[0:1])
         comp2 = Compare(node.comparators[0], node.ops[1:],
                         node.comparators[1:])
         newNode = BoolOp(And(), [comp1, self.compBreaker(comp2)])
         return newNode
Example #3
0
 def _if_gt(value):
     if value >= 0:
         comparators = [Constant(value=value, kind=None)]
     else:
         comparators = [
             UnaryOp(
                 op=USub(),
                 operand=Constant(value=abs(value), kind=None),
             ),
         ]
     return [
         If(
             test=Compare(
                 left=Call(
                     func=Name(id='int', ctx=Load()),
                     args=[Name(id='value', ctx=Load())],
                     keywords=[],
                 ),
                 ops=[Gt()],
                 comparators=comparators,
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         )
     ]
Example #4
0
        def _generate_assignment((arg_name, arg_resource_handle)):
            # type: (Tuple[basestring, int]) -> If
            """
            We have a function that looks like:
            def do_something(param, model_=INJECTED):
                <...>

            We insert into its beginning a statement like
                ___INJECT_CONTEXT_INTERNAL_RESOURCES = ___INJECT_CONTEXT_INTERNAL.resources
                if model_ is INJECTED:
                    model_ = ___INJECT_CONTEXT_INTERNAL_RESOURCES[3]
                    if model is ___INJECT_CONTEXT_INTERNAL:    # means that no resource is available
                        ___INJECT_CONTEXT_INTERNAL_RESOURCES.flag_missing('model_')

            Code outside of this function sets a global variable _INJECTED__model to point at the right thing.
            """
            target_attribute = Subscript(
                value=Name(id=INTERNAL_RESOURCES_NAME, ctx=Load()),
                slice=Index(value=Num(n=arg_resource_handle)),
                ctx=Load())

            consequence = [
                Assign(targets=[Name(id=arg_name, ctx=Store())],
                       value=target_attribute),
                If(test=Compare(
                    left=Name(id=arg_name, ctx=Load()),
                    ops=[Is()],
                    comparators=[Name(id=INTERNAL_CONTEXT_NAME, ctx=Load())]),
                   body=[
                       Expr(value=Call(func=Attribute(value=Name(
                           id=INTERNAL_CONTEXT_NAME, ctx=Load()),
                                                      attr='flag_missing',
                                                      ctx=Load()),
                                       keywords=[],
                                       starargs=None,
                                       kwargs=None,
                                       args=[Str(s=arg_name)]))
                   ],
                   orelse=[])
            ]  # type: List[Union[Assign, If]

            return If(test=Compare(
                left=Name(id=arg_name, ctx=Load()),
                ops=[Is()],
                comparators=[default_nodes_mapping[arg_name]]),
                      body=consequence,
                      orelse=[])
Example #5
0
    def visit_Compare(self, compare: ast.Compare) -> Optional[IType]:
        """
        Verifies if the types of the operands are valid to the compare operations

        If the operations are valid, changes de Python operator by the Boa operator in the syntax tree

        :param compare: the python ast compare operation node
        :return: the type of the result of the operation if the operation is valid. Otherwise, returns None
        :rtype: IType or None
        """
        if len(compare.comparators) != len(compare.ops):
            self._log_error(
                CompilerError.IncorrectNumberOfOperands(
                    compare.lineno,
                    compare.col_offset,
                    len(compare.ops),
                    len(compare.comparators) + 1  # num comparators + compare.left
                )
            )

        line = compare.lineno
        col = compare.col_offset
        try:
            return_type = None
            l_operand = self.visit_value(compare.left)
            for index, op in enumerate(compare.ops):
                operator: Operator = self.get_operator(op)
                r_operand = self.visit_value(compare.comparators[index])

                if not isinstance(operator, Operator):
                    # the operator is invalid or it was not implemented yet
                    self._log_error(
                        CompilerError.UnresolvedReference(line, col, type(op).__name__)
                    )

                operation: IOperation = self.get_bin_op(operator, r_operand, l_operand)
                if operation is None:
                    self._log_error(
                        CompilerError.NotSupportedOperation(line, col, operator)
                    )
                elif not operation.is_supported:
                    # TODO: is, is not and eq were not implemented yet
                    self._log_error(
                        CompilerError.NotSupportedOperation(line, col, operator)
                    )
                else:
                    compare.ops[index] = operation
                    return_type = operation.result

                line = compare.comparators[index].lineno
                col = compare.comparators[index].col_offset
                l_operand = r_operand

            return return_type
        except CompilerError.MismatchedTypes as raised_error:
            raised_error.line = line
            raised_error.col = col
            # raises the exception with the line/col info
            self._log_error(raised_error)
Example #6
0
 def emit(self):
     assign = IfExp(test=Compare(
         left=Str(s=self.name),
         ops=[In()],
         comparators=[Call(func=Name(id="dir", ctx=Load()))]),
                    body=Name(id=self.name, ctx=Load()),
                    orelse=Call(func=Name(id='Void', ctx=Load())))
     return Log.log(self.name, assign)
Example #7
0
 def visit_Compare(self, node):
     self.generic_visit(node)
     unitcalc = UnitCalculator(self.localDict)
     leftUD = unitcalc.getUnitAndDim(node.left)
     listUD = [unitcalc.getUnitAndDim(comp) for comp in node.comparators]
     nonNoneDims = [ud[1] for ud in listUD + [leftUD] if ud[1] is not None]
     for dims in nonNoneDims:
         checkDimensions(nonNoneDims[0], dims)
     factorlist = [ud[0] / leftUD[0] for ud in listUD]
     newComplist = [withFactor(*t) \
                    for t in zip(factorlist, node.comparators)]
     compOp = Compare(node.left, node.ops, newComplist)
     compOpTrans = self.compBreaker(compOp)
     return compOpTrans
Example #8
0
    def comparison(self, c):
        x: Union[Tree, Name]
        y: Union[Tree, Name]
        check: Token
        x, check, y = c

        func = {
            '==': Eq,
            '!=': NotEq,
            '<': Lt,
            '<=': LtE,
            '>': Gt,
            '>=': GtE,
        }.get(check.value, None)

        if isinstance(x, list):
            x = x[0]

        if isinstance(x, Tree):
            if x.data == 'var':
                x = x.children[0]

        if isinstance(y, list):
            temp = []
            for i in y:
                if isinstance(i, Tree):
                    if i.data == 'var':
                        i = i.children[0]
                if isinstance(i, Name):
                    i = self.LoadName(i.id)
                temp.append(i)
            y = temp
        if isinstance(y, Tree):
            if y.data == 'var':
                y = y.children[0]

        if isinstance(x, Name):
            x = self.LoadName(x.id)
        if isinstance(y, Name):
            y = self.LoadName(y.id)

        if func is not None:
            return Compare(left=x, ops=[func()], comparators=y)

        else:
            raise TypeError(f'Unrecognised comparison operator: {check.value}')
Example #9
0
def setter_body(item):
    """Construct the body of the setter function.
    """
    new_value = Name(id="new", ctx=ast.Load())
    inst_var = Attribute(value=Name(id="self", ctx=ast.Load()),
                         attr=f"_{item.var}",
                         ctx=ast.Store())
    comp_node = Compare(
        left=Num(n=item.lower),
        ops=[ast.Lt(), ast.Lt()],
        comparators=[new_value, Num(n=item.upper)],
    )
    assign_stmt = ast.Assign(targets=[inst_var], value=new_value)
    except_msg = f"value outside of range {item.lower} < {item.var} < {item.upper}"
    exc = ast.Call(
        func=Name(id="ValueError", ctx=ast.Load()),
        args=[ast.Str(s=except_msg)],
        keywords=[],
    )
    else_body = ast.Raise(exc=exc, cause=None)
    if_node = ast.If(test=comp_node, body=[assign_stmt], orelse=[else_body])
    return if_node
Example #10
0
 def _if_length(self, minimum, maximum):
     return [
         If(
             test=Compare(
                 left=Constant(value=int(minimum), kind=None),
                 ops=[
                     Gt(),
                     Gt(),
                 ],
                 comparators=[
                     Call(
                         func=Name(id='len', ctx=Load()),
                         args=[Name(id='value', ctx=Load())],
                         keywords=[],
                     ),
                     Constant(value=int(maximum), kind=None),
                 ],
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         ),
     ]
    def handle_f(self, f):
        # Do we need to use .attname here?
        # What about transforms/lookups?
        f.contains_aggregate = False
        if "__" in f.name:
            # We need to chain a bunch of attr lookups, returning None
            # if any of them give us a None, we should be returning a None.
            #

            # .  while x is not None and parts:
            # .      x = getattr(x, parts.pop(0), None)
            #   return x
            return [
                Assign(targets=[Name(id="source", **self.file_store)],
                       value=Name(id="self", **self.file),
                       **self.file),
                Assign(
                    targets=[Name(id="parts", **self.file_store)],
                    value=Call(
                        func=Attribute(value=Constant(value=f.name,
                                                      **self.file),
                                       attr="split",
                                       **self.file),
                        args=[Constant(value="__", **self.file)],
                        keywords=[],
                        kwonlyargs=[],
                        **self.file,
                    ),
                    **self.file,
                ),
                While(
                    test=BoolOp(
                        op=And(),
                        values=[
                            Compare(
                                left=Name(id="source", **self.file),
                                ops=[IsNot()],
                                comparators=[
                                    Constant(value=None, **self.file)
                                ],
                                **self.file,
                            ),
                            Name(id="parts", **self.file),
                        ],
                        **self.file,
                    ),
                    body=[
                        Assign(
                            targets=[Name(id="source", **self.file_store)],
                            value=Call(
                                func=Name(id="getattr", **self.file),
                                args=[
                                    Name(id="source", **self.file),
                                    Call(
                                        func=Attribute(value=Name(id="parts",
                                                                  **self.file),
                                                       attr="pop",
                                                       **self.file),
                                        args=[Constant(value=0, **self.file)],
                                        keywords=[],
                                        kwonlyargs=[],
                                        **self.file,
                                    ),
                                    Constant(value=None, **self.file),
                                ],
                                keywords=[],
                                kwonlyargs=[],
                                **self.file,
                            ),
                            **self.file,
                        ),
                    ],
                    orelse=[],
                    **self.file,
                ),
                Return(value=Name(id="source", **self.file), **self.file),
            ]
        return Attribute(value=Name(id="self", **self.file),
                         attr=f.name,
                         **self.file)
Example #12
0
def comparison(ra, ctx, op):
    return Compare(
        left=convert(ra[0], ctx),
        ops=[op],
        comparators=[convert(ra[1], ctx)],
    )
Example #13
0
def empty_script_tree(project_id: str, add_main_loop: bool = True) -> Module:
    """Creates barebones of the script (empty 'main' function).

    Returns
    -------
    """

    main_body: List[stmt] = [
        Assign(
            targets=[Name(id="aps", ctx=Store())],
            value=Call(func=Name(id="ActionPoints", ctx=Load()),
                       args=[Name(id="res", ctx=Load())],
                       keywords=[]),
            type_comment=None,
        )
    ]

    if add_main_loop:
        main_body.append(
            While(test=NameConstant(value=True, kind=None),
                  body=[Pass()],
                  orelse=[]))
    else:
        """put there "pass" in order to make code valid even if there is no
        other statement (e.g. no object from resources)"""
        main_body.append(Pass())

    # TODO helper function for try ... except

    tree = Module(
        body=[
            FunctionDef(
                name="main",
                args=arguments(
                    args=[
                        arg(arg="res",
                            annotation=Name(id=RES_CLS, ctx=Load()),
                            type_comment=None)
                    ],
                    vararg=None,
                    kwonlyargs=[],
                    kw_defaults=[],
                    kwarg=None,
                    defaults=[],
                ),
                body=main_body,
                decorator_list=[],
                returns=NameConstant(value=None, kind=None),
                type_comment=None,
            ),
            If(
                test=Compare(left=Name(id="__name__", ctx=Load()),
                             ops=[Eq()],
                             comparators=[Str(s="__main__", kind="")]),
                body=[
                    Try(
                        body=[
                            With(
                                items=[
                                    withitem(
                                        context_expr=Call(
                                            func=Name(id=RES_CLS, ctx=Load()),
                                            args=[Str(s=project_id, kind="")],
                                            keywords=[],
                                        ),
                                        optional_vars=Name(id="res",
                                                           ctx=Store()),
                                    )
                                ],
                                body=[
                                    Expr(value=Call(
                                        func=Name(id="main", ctx=Load()),
                                        args=[Name(id="res", ctx=Load())],
                                        keywords=[],
                                    ))
                                ],
                                type_comment=None,
                            )
                        ],
                        handlers=[
                            ExceptHandler(
                                type=Name(id=Exception.__name__, ctx=Load()),
                                name="e",
                                body=[
                                    Expr(value=Call(
                                        func=Name(id=arcor2.exceptions.runtime.
                                                  print_exception.__name__,
                                                  ctx=Load()),
                                        args=[Name(id="e", ctx=Load())],
                                        keywords=[],
                                    ))
                                ],
                            )
                        ],
                        orelse=[],
                        finalbody=[],
                    )
                ],
                orelse=[],
            ),
        ],
        type_ignores=[],
    )

    add_import(tree, arcor2.exceptions.runtime.__name__,
               arcor2.exceptions.runtime.print_exception.__name__)
    add_import(tree, RES_MODULE, RES_CLS, try_to_import=False)
    add_import(tree, "action_points", "ActionPoints", try_to_import=False)

    return tree
Example #14
0
def _(ra: ras.Join, ctx: Context):
    # Function
    body_ast = ast.parse(inspect.getsource(MERGE_EQUI_JOIN_FUNC))

    # Loop body
    merge_func_ast = body_ast.body[0]
    merge_func_ast.name = unique_name('merge')

    # Create row comparison
    func_name = unique_name('cmp')
    func_args = [
        ast.arg(arg='left', annotation=None),
        ast.arg(arg='right', annotation=None),
    ]
    # val = ast.BinOp(
    #     left=convert(ra.operands[0].operands[1], ctx, var_name='left'),
    #     op=ast.Sub(),
    #     right=convert(ra.operands[1].operands[1], ctx, var_name='right'),
    # )
    # func_return = ast.Return(value=val)
    left = convert(ra.operands[0].operands[1], ctx, var_name='left')
    right = convert(ra.operands[1].operands[1], ctx, var_name='right')
    if_statement = ast.If(
        test=Compare(left=left, ops=[
            ast.Lt(),
        ], comparators=[
            right,
        ]),
        body=[
            ast.Return(value=ast.UnaryOp(op=ast.USub(), operand=ast.Num(n=1))),
        ],
        orelse=[
            ast.If(test=Compare(left=left,
                                ops=[
                                    ast.Gt(),
                                ],
                                comparators=[
                                    right,
                                ]),
                   body=[
                       ast.Return(value=ast.Num(n=1)),
                   ],
                   orelse=[
                       ast.Return(value=ast.Num(n=0)),
                   ]),
        ])
    func_cmp = FunctionDef(name=func_name,
                           args=ast.arguments(args=func_args,
                                              vararg=None,
                                              kwonlyargs=[],
                                              kw_defaults=[],
                                              kwarg=None,
                                              defaults=[]),
                           body=[if_statement],
                           decorator_list=[],
                           returns=None)
    merge_func_ast.body.insert(0, func_cmp)

    # Inject functions
    body_ast = ast_transformer.FindAndReplaceNames({
        '__cmp_func__': func_cmp,
    }).visit(body_ast)

    ast.fix_missing_locations(body_ast)

    logger.debug(astor.to_source(body_ast))

    return body_ast
Example #15
0
    def _add_logic(container: Container,
                   current_action: Action,
                   super_container: Optional[Container] = None) -> None:

        # more paths could lead  to the same action, so it might be already added
        # ...this is easier than searching the tree
        if current_action.id in added_actions:
            logger.debug(
                f"Action {current_action.name} already added, skipping.")
            return

        inputs, outputs = project.action_io(current_action.id)
        logger.debug(
            f"Adding action {current_action.name}, with {len(inputs)} input(s) and {len(outputs)} output(s)."
        )

        act = current_action.parse_type()
        ac_obj = scene.object(act.obj_id).name

        args: List[AST] = []

        # TODO make sure that the order of parameters is correct / re-order
        for param in current_action.parameters:

            if param.type == ActionParameter.TypeEnum.LINK:

                parsed_link = param.parse_link()
                parent_action = project.action(parsed_link.action_id)

                # TODO add support for tuples
                assert len(parent_action.flow(FlowTypes.DEFAULT).outputs
                           ) == 1, "Only one result is supported atm."
                assert parsed_link.output_index == 0

                res_name = parent_action.flow(FlowTypes.DEFAULT).outputs[0]

                # make sure that the result already exists
                if parent_action.id not in added_actions:
                    raise SourceException(
                        f"Action {current_action.name} attempts to use result {res_name} "
                        f"of subsequent action {parent_action.name}.")

                args.append(Name(id=res_name, ctx=Load()))

            elif param.type == ActionParameter.TypeEnum.PROJECT_PARAMETER:
                args.append(
                    Name(id=project.parameter(param.str_from_value()).name,
                         ctx=Load()))
            else:

                plugin = plugin_from_type_name(param.type)

                args.append(
                    plugin.parameter_ast(type_defs, scene, project,
                                         current_action.id, param.name))

                list_of_imp_tup = plugin.need_to_be_imported(
                    type_defs, scene, project, current_action.id, param.name)

                if list_of_imp_tup:
                    # TODO what if there are two same names?
                    for imp_tup in list_of_imp_tup:
                        add_import(tree,
                                   imp_tup.module_name,
                                   imp_tup.class_name,
                                   try_to_import=False)

        add_method_call(
            container.body,
            ac_obj,
            act.action_type,
            args,
            [keyword(arg="an", value=Str(s=current_action.name, kind=""))],
            current_action.flow(FlowTypes.DEFAULT).outputs,
        )

        added_actions.add(current_action.id)

        if not outputs:
            raise SourceException(
                f"Action {current_action.name} has no outputs.")
        elif len(outputs) == 1:
            output = outputs[0]

            if output.end == output.END:
                # TODO this is just temporary (while there is while loop), should be rather Return()
                container.body.append(Continue())
                return

            seq_act = project.action(output.end)
            seq_act_inputs, _ = project.action_io(seq_act.id)
            if len(seq_act_inputs
                   ) > 1:  # the action belongs to a different block

                if seq_act.id in added_actions:
                    return

                logger.debug(
                    f"Action {seq_act.name} going to be added to super_container."
                )

                # test if this is the correct super_container -> count distance (number of blocks) to the START
                blocks_to_start: Dict[str, int] = {}

                for inp in seq_act_inputs:
                    parsed_start = inp.parse_start()
                    pact = project.action(parsed_start.start_action_id)
                    blocks_to_start[pact.id] = _blocks_to_start(pact)
                winner = min(blocks_to_start, key=blocks_to_start.get
                             )  # type: ignore  # TODO what is wrong with it?

                # TODO if blocks_to_start is cached somewhere, the second part of the condition is useless
                # it might happen that there are two different ways with the same distance
                if winner == current_action.id or all(
                        value == list(blocks_to_start.values())[0]
                        for value in blocks_to_start.values()):
                    assert super_container is not None
                    _add_logic(super_container, seq_act)
                return

            logger.debug(f"Sequential action: {seq_act.name}")
            _add_logic(container, seq_act, super_container)

        else:

            root_if: Optional[If] = None

            # action has more outputs - each output should have condition
            for idx, output in enumerate(outputs):
                if not output.condition:
                    raise SourceException("Missing condition.")

                # TODO use parameter plugin (action metadata will be needed - to get the return types)
                # TODO support for other countable types
                # ...this will only work for booleans
                from arcor2 import json

                condition_value = json.loads(output.condition.value)
                comp = NameConstant(value=condition_value, kind=None)
                what = output.condition.parse_what()
                output_name = project.action(what.action_id).flow(
                    what.flow_name).outputs[what.output_index]

                cond = If(
                    test=Compare(left=Name(id=output_name, ctx=Load()),
                                 ops=[Eq()],
                                 comparators=[comp]),
                    body=[],
                    orelse=[],
                )

                if idx == 0:
                    root_if = cond
                    container.body.append(root_if)
                    logger.debug(f"Adding branch for: {condition_value}")
                else:
                    assert isinstance(root_if, If)
                    root_if.orelse.append(cond)

                if output.end == output.END:
                    cond.body.append(
                        Continue())  # TODO should be rather return
                    continue

                _add_logic(cond, project.action(output.end), container)
Example #16
0
"""

if __name__ == "__main__":
    mod = Module(body=[
        FunctionDef(name='F_6',
                    args=arguments(args=[
                        arg(arg='x', annotation=Name(id='int', ctx=Load())),
                        arg(arg='y', annotation=None)
                    ],
                                   vararg=arg(arg='args',
                                              annotation=List(elts=[
                                                  Name(id='str', ctx=Load())
                                              ],
                                                              ctx=Load())),
                                   kwonlyargs=[],
                                   kw_defaults=[],
                                   kwarg=None,
                                   defaults=[]),
                    body=[
                        Return(value=Compare(left=Name(id='x', ctx=Load()),
                                             ops=[Eq()],
                                             comparators=[Num(n=6)]))
                    ],
                    decorator_list=[],
                    returns=Name(id='bool', ctx=Load()))
    ])
    expr_ast = parse(expr)
    print(expr_ast)
    print(f"{dump(expr_ast)}\n")
    print(unparse(mod))
Example #17
0
 def boolexpr(self, tree):
     from ast import Compare
     return Compare(tree[0], [tree[1]], comparators=[tree[2]])