示例#1
0
    def visit_match(self, match: Expr):
        """For matches, we wrap the entire expression in a thunk
        because it is easiest to implement them using if statements.
        For each clause, we generate a function that checks if the
        pattern matches. If yes, we call a function that assigns
        the variables appropriately and invokes the clause body."""
        data, defs = self.visit(match.data)
        data_var = self.generate_var_name("_match_data")

        # must ensure the data clause is executed exactly once
        thunk_body = [Assign([Name(data_var, Store())], data)]
        for clause in match.clauses:
            check_expr = self.create_match_check(clause.lhs,
                                                 Name(data_var, Load()))
            body_def, body_name = self.create_match_clause_body(
                clause.lhs, clause.rhs)
            defs.append(body_def)

            # equiv: if check(data): return body(data)
            thunk_body.append(
                ast.If(check_expr, [
                    Return(
                        self.create_call(body_name, [Name(data_var, Load())]))
                ], []))

        # finally if nothing matches we have a failed assert (should never happen)
        thunk_body.append(
            ast.Assert(NameConstant(False), Str("Match was not exhaustive")))

        thunk_name = self.generate_function_name("_match_thunk")
        thunk_def = self.create_def(thunk_name, [], defs + thunk_body)
        return (self.create_call(thunk_name, []), [thunk_def])
示例#2
0
def set_value(value, kind=None):
    """
    Creates a Constant or a Str depending on Python version in use

    :param value: AST node
    :type value: ```Any```

    :param kind: AST node
    :type kind: ```Optional[Any]```

    :return: Probably a string, but could be any constant value
    :rtype: ```Union[Constant, Str, NameConstant]```
    """
    if (
        value is not None
        and isinstance(value, str)
        and len(value) > 2
        and value[0] + value[-1] in frozenset(('""', "''"))
    ):
        value = value[1:-1]
    return (
        Constant(kind=kind, value=value, constant_value=None, string=None)
        if PY_GTE_3_8
        else (
            Str(s=value, constant_value=None, string=None)
            if isinstance(value, str)
            else Num(n=value, constant_value=None, string=None)
            if not isinstance(value, bool) and isinstance(value, (int, float, complex))
            else NameConstant(value=value, constant_value=None, string=None)
        )
    )
示例#3
0
    def visit_call(self, call: Expr):
        """For calls, we must distinguish between ordinary functions,
        operators, and constructor calls."""
        func = call.op
        fields, field_defs = self.convert_fields(call.args)

        if isinstance(func, tvm.ir.Op):
            raise Exception(
                'Operators should have been lowered and eliminated')

        if isinstance(func, relay.Constructor):
            # produce a constructor value
            return (self.create_call('ConstructorValue', [
                ast.Num(func.tag),
                ast.List(fields, Load()),
                NameConstant(None)
            ]), field_defs)

        # lowered operator: generate a call to a function that gets the PackedFunc
        # from TVM's registry
        if isinstance(
                func,
                Function) and func.attrs and func.attrs.Primitive.value == 1:
            op_call_def, op_call = self.create_op_call(func, call.args, fields)
            return (op_call, field_defs + [op_call_def])

        # ordinary function
        converted_func, defs = self.visit(func)
        defs += field_defs
        return (ast.Call(converted_func, fields, []), defs)
示例#4
0
文件: ast.py 项目: barry-scott/xonsh
def _getblockattr(name, lineno, col):
    """calls getattr(name, '__xonsh_block__', False)."""
    return xonsh_call('getattr', args=[
        Name(id=name, ctx=Load(), lineno=lineno, col_offset=col),
        Str(s='__xonsh_block__', lineno=lineno, col_offset=col),
        NameConstant(value=False, lineno=lineno, col_offset=col)],
        lineno=lineno, col=col)
示例#5
0
    def update_values(self, values: dict):
        self._updated = True
        self.check_populated()

        for name, value in values.items():
            statement = NameConstant(value)
            if statement not in self._statement_to_thunk:
                self._statement_to_thunk[statement] = ValueThunk(value)

            self._set_thunk(name, self._statement_to_thunk[statement])
示例#6
0
文件: logic.py 项目: NelaMm/arcor2
def program_src(type_defs: TypesDict,
                project: CProject,
                scene: CScene,
                add_logic: bool = True) -> str:

    tree = empty_script_tree(project.id, add_main_loop=add_logic)

    # get object instances from resources object
    main = find_function("main", tree)
    last_assign = find_last_assign(main)
    for obj in scene.objects:
        add_import(tree,
                   "object_types." + humps.depascalize(obj.type),
                   obj.type,
                   try_to_import=False)
        last_assign += 1
        main.body.insert(last_assign,
                         object_instance_from_res(obj.name, obj.id, obj.type))

    # TODO temporary solution - should be (probably) handled by plugin(s)
    from arcor2 import json

    # TODO should we put there even unused parameters?
    for param in project.parameters:
        val = json.loads(param.value)

        aval: Optional[expr] = None

        if isinstance(val, bool):  # subclass of int
            aval = NameConstant(value=val, kind=None)
        elif isinstance(val, (int, float)):
            aval = Num(n=val, kind=None)
        elif isinstance(val, str):
            aval = Str(s=val, kind="")

        if not aval:
            raise Arcor2Exception(
                f"Unsupported project parameter type ({param.type}) or value ({val})."
            )

        last_assign += 1
        main.body.insert(
            last_assign,
            Assign(  # TODO use rather AnnAssign?
                targets=[Name(id=param.name, ctx=Store())],
                value=aval,
                type_comment=None),
        )

    if add_logic:
        add_logic_to_loop(type_defs, tree, scene, project)

    return SCRIPT_HEADER + tree_to_str(tree)
示例#7
0
    def parse_numpy_array(self, arr):
        """Given a Numpy array, produces an appropriate Python array
        or numerical literal representing its contents."""
        parse_single = lambda i: NameConstant(i) if isinstance(i, bool) else Num(i)
        if arr.ndim == 0:
            return parse_single(arr.item())
        if arr.ndim == 1:
            return ast.List([parse_single(i.item()) for i in arr], Load())

        elts = []
        for row in arr:
            elts.append(self.parse_numpy_array(row))
        return ast.List(elts, Load())
示例#8
0
    def create_match_check(self, pattern: Pattern, data):
        """Given an ADT match pattern and a (Python) expression pointing to
        an ADT value, this generates a Python expression that checks if the
        ADT value matches the given pattern (returning True or False)."""

        # wildcard or var match everything
        if isinstance(pattern, (relay.PatternWildcard, relay.PatternVar)):
            return NameConstant(True)

        conds = []

        if isinstance(pattern, relay.PatternConstructor):
            # constructor patterns check whether the constructors match
            # and also the matches of any nested patterns

            # equiv: (arg.tag == patern_constructor.tag)
            conds.append(
                ast.Compare(
                    ast.Attribute(data, "tag", Load()),
                    [ast.Eq()],
                    [ast.Num(pattern.constructor.tag)],
                )
            )

        assert isinstance(pattern, (relay.PatternConstructor, relay.PatternTuple))
        # now check for any nested patterns
        for i in range(len(pattern.patterns)):
            nested_pat = pattern.patterns[i]
            # can safely skip var or wildcard patterns: they will
            # never cause a check to fail
            if not isinstance(nested_pat, relay.PatternConstructor):
                continue

            # index into the value corresponding to the subpattern
            field_index = ast.Subscript(
                ast.Attribute(data, "fields", Load()), ast.Index(Num(i)), Load()
            )
            conds.append(self.create_match_check(nested_pat, field_index))

        # if we do not need to check nested pattern, just return the single check
        if len(conds) == 1:
            return conds[0]
        # otherwise AND together any nested checks
        return ast.BoolOp(ast.And(), conds)
示例#9
0
文件: castt.py 项目: tdrjnr/ayrton
    def visit_For(self, node):
        # For(target=Name(id='x', ctx=Store()), iter=List(elts=[], ctx=Load()),
        #     body=[Pass()], orelse=[])
        # For(target=Tuple(elts=[Name(id='band', ctx=Store()), Name(id='color', ctx=Store())], ctx=Store()),
        #     iter=Tuple(elts=[...], ctx=Load()),
        #     body=[Pass()], orelse=[])
        self.bind(node.target)
        self.generic_visit(node)

        # if iter is Command, set _out=Capture
        # so this works as expected:
        # for line in ls(): ...

        # For(target=Name(id='line', ctx=Store()),
        #     iter=Call(func=Call(func=Name(id='Command', ctx=Load()), ...
        if is_executable(node.iter):
            update_keyword(
                node.iter,
                keyword(arg='_out', value=Name(id='Capture', ctx=Load())))
            update_keyword(node.iter,
                           keyword(arg='_bg', value=NameConstant(value=True)))

        return node
示例#10
0
def new_object_type(parent: ObjectTypeMeta, child: ObjectTypeMeta) -> AST:

    assert parent.type == child.base

    tree = Module(body=[], type_ignores=[])

    if parent.type in built_in_types_names():
        import_from = arcor2.object_types.abstract.__name__
    else:
        import_from = f".{humps.depascalize(parent.type)}"

    tree.body.append(
        ImportFrom(module=import_from,
                   names=[alias(name=parent.type, asname=None)],
                   level=0))

    c = ClassDef(
        name=child.type,
        bases=[get_name(parent.type)],
        keywords=[],
        body=[
            Assign(
                targets=[Name(id="_ABSTRACT", ctx=Store())],
                value=NameConstant(value=False, kind=None),
                type_comment=None,
            )
        ],
        decorator_list=[],
    )

    # TODO add docstring with description (if provided)
    c.body.append(Pass())

    tree.body.append(c)

    return tree
示例#11
0
		def visit_FunctionDef(self, node: ast.FunctionDef):
			if len(node.body)>0 and isinstance(node.body[0],Expr) and isinstance(node.body[0].value,Str) and node.body[0].value.s == 'dbg_ignore':
				oldHHRC = self.hotHasReturnCheck
				oldBV = self.hot
				self.hotHasReturnCheck = False
				self.hot = None
				self.generic_visit(node)
				self.hotHasReturnCheck = oldHHRC
				self.hot = oldBV
				return node
			# print("visiting",node.name)
			frozone = len(self.funcNames)
			self.funcNames.append(node.name)#+str(node.lineno)
			if hasattr(node,'definedforclass'):
				self.classowners.append(node.definedforclass)
			else:
				self.classowners.append(None)
			self.scopes.append(0)
			self.funcparams.append([k.arg for k in node.args.args])
			hasEnter = False
			hasExit = False
			fpad = 2
			if len(node.body)>0:
				if  self.isEnterFunc(node.body[0]): hasEnter=True
				elif self.isExitFunc(node.body[0],node.args.args): hasExit=True
				else: fpad-=1
			else: fpad-=1
			if len(node.body)>1:
				if  self.isEnterFunc(node.body[1]): hasEnter=True
				elif self.isExitFunc(node.body[1],node.args.args): hasExit=True
				else: fpad-=1
			else: fpad-=1

			oldHHRC = self.hotHasReturnCheck
			oldBV = self.hot
			self.hotHasReturnCheck = hasExit
			self.hot = frozone
			self.generic_visit(node)


			if len(self.exitpatterns.get(node.name,[])) > len(node.args.args):
				print("Exit pattern for function ",node.name," has too many parameters.")
				assert False

			shobb = []
			for z in range(len(node.args.args) if hasExit else len(self.exitpatterns.get(node.name,[]))):
				# print("Assign2: ",str(frozone))
				shobb.append(Assign(
					targets=[Name(id=node.args.args[z].arg+'_dbg_str_var_'+str(frozone), ctx=Store())],
					value=Name(id=node.args.args[z].arg,ctx=Load())
				))

			if hasExit:
				expattern = [k.arg for k in node.args.args]
				# sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit', ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))


				node.body.append(Expr(value=Call(func=Name(id='_dbgExit', ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[NameConstant(value=None)], keywords=[])))
			if node.name in self.exitpatterns:
				expattern = self.exitpatterns[node.name]
				if len(node.args.args)<len(expattern) or expattern != [k.arg for k in node.args.args][:len(expattern)]:
					print("You defined an exit pattern, "+node.name+", and then you define a function with different first N parameters from it.")
					assert False


				node.body.append(Expr(value=Call(func=Name(id='_dbgExit_'+node.name, ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[NameConstant(value=None)], keywords=[])))

			track_frames = False
			freebody = node.body[fpad:]+[]
			if track_frames:
				freebody = [With(
					items=[
						withitem(
							context_expr=Call(func=Attribute(value=Name(id='madscience_debugger', ctx=Load()), attr='push_context', ctx=Load()), args=[Num(n=frozone)], keywords=[]),
							optional_vars=Name(id='madscience_debug_context', ctx=Store())
						)
					],
					body=node.body[fpad:]+[]
				)]

			node.body = shobb + node.body[:fpad] + freebody
			

			if track_frames:
				self.visitblock(node.body[-1].body,"func")
			else:
				self.visitblock(node.body[-1],"func")
			# if node.name=="verify":
			# 	print("verify mutated",node.lineno)
			# 	node.body.insert(0,Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='function was knocked on '+str(node.lineno))], keywords=[])))
			# 	node.body[-1].body.insert(0,Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='function was visited '+str(node.lineno))], keywords=[])))
			# print("mutated",node.name)
			# print(self.enterpatterns,frozone,node.name)
			if hasEnter: node.body.insert(fpad+len(shobb),Expr(value=Call(func=Name(id='_dbgEnter', ctx=Load()), args=[], keywords=[])))
			if node.name in self.enterpatterns:
				# print("enter pattern added.")
				expattern = self.enterpatterns[node.name]
				if len(node.args.args)<len(expattern) or expattern != [k.arg for k in node.args.args][:len(expattern)]:
					print("You defined an enter pattern, "+node.name+", and then you define a function with different first N parameters from it.")
					assert False
				node.body.insert(fpad+len(shobb),Expr(value=Call(func=Name(id='_dbgEnter_'+node.name, ctx=Load()), args=[Name(id=pn,ctx=Load()) for pn in expattern], keywords=[])))
			ast.fix_missing_locations(node)
			if self.isTestFunc(node):
				# self.generic_visit(node)
				sin = [
					node,
					Expr(value=Call(func=Name(id='_dbgTest', ctx=Load()), args=[], keywords=[]))
				]
				ast.copy_location(sin[1], node)
				ast.fix_missing_locations(sin[1])
				return sin
			self.absorbEnterPattern(node)
			self.absorbExitPattern(node)
			# print()
			# print(ast.dump(node))
			self.hotHasReturnCheck = oldHHRC
			self.hot = oldBV



			return node
示例#12
0
文件: utils.py 项目: Croolman/arcor2
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
示例#13
0
文件: logic.py 项目: NelaMm/arcor2
    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)
示例#14
0
 def parse_single(i):
     return NameConstant(i) if isinstance(i, bool) else Num(i)
示例#15
0
def name_constant(value, loc=None):
    return cl(NameConstant(value), loc)
示例#16
0
文件: boolean.py 项目: robofit/arcor2
 def parameter_ast(cls, type_defs: TypesDict, scene: CScene,
                   project: CProject, action_id: str,
                   parameter_id: str) -> NameConstant:
     return NameConstant(value=cls.parameter_execution_value(
         type_defs, scene, project, action_id, parameter_id),
                         kind=None)