Ejemplo n.º 1
0
Archivo: call.py Proyecto: ztane/jaspyx
    def visit_Call(self, node):
        if node.keywords:
            raise Exception('keyword arguments are not supported')
        if node.kwargs is not None:
            raise Exception('kwargs is not supported')

        if isinstance(node.func, _ast.Name):
            func = getattr(self, 'func_%s' % node.func.id, None)
            if func is not None:
                # noinspection PyCallingNonCallable
                return func(*node.args)

        if not node.starargs:
            self.visit(node.func)
            self.group(node.args, infix=', ')
        else:
            # Rewrite the call without starargs using apply.
            if isinstance(node.func, _ast.Attribute):
                this = node.func.value
            else:
                this = ast_load('this')
            if not node.args:
                args = node.starargs
            else:
                args = ast_call(
                    ast.Attribute(ast.List(node.args, ast.Load()), 'concat',
                                  ast.Load()), node.starargs)
            self.visit(
                ast_call(
                    ast.Attribute(node.func, 'apply', ast.Load()),
                    this,
                    args,
                ))
Ejemplo n.º 2
0
def _new_constant(node, value):
    if isinstance(value, ast.AST):
        # convenient shortcut: return the AST object unchanged
        return value

    # FIXME: test the config directly here?

    if value is None:
        new_node = ast.Constant(value=None)
    elif isinstance(value, (bool, int, float, complex, str, bytes)):
        new_node = ast.Constant(value=value)
    elif isinstance(value, (tuple, frozenset)):
        if not _is_constant(value):
            raise TypeError("container items are not constant: %r" % (value, ))
        new_node = ast.Constant(value=value)
    elif isinstance(value, list):
        elts = [_new_constant(node, elt) for elt in value]
        new_node = ast.List(elts=elts, ctx=ast.Load())
    elif isinstance(value, dict):
        keys = []
        values = []
        for key, value in value.items():
            keys.append(_new_constant(node, key))
            values.append(_new_constant(node, value))
        new_node = ast.Dict(keys=keys, values=values, ctx=ast.Load())
    elif isinstance(value, set):
        elts = [_new_constant(node, elt) for elt in value]
        new_node = ast.Set(elts=elts, ctx=ast.Load())
    else:
        raise TypeError("unknown type: %s" % type(value).__name__)

    copy_lineno(node, new_node)
    return new_node
Ejemplo n.º 3
0
    def translate(self):
        """Compile the function call."""
        varnames = set()
        if six.PY2:
            ident = self.ident.encode('utf-8')
        else:
            ident = self.ident
        funcnames = set([ident])

        arg_exprs = []
        for arg in self.args:
            subexprs, subvars, subfuncs = arg.translate()
            varnames.update(subvars)
            funcnames.update(subfuncs)

            # Create a subexpression that joins the result components of
            # the arguments.
            arg_exprs.append(
                ex_call(
                    ast.Attribute(ex_literal(u''), 'join', ast.Load()),
                    [
                        ex_call('map', [
                            ex_rvalue(six.text_type.__name__),
                            ast.List(subexprs, ast.Load()),
                        ])
                    ],
                ))

        subexpr_call = ex_call(FUNCTION_PREFIX + ident, arg_exprs)
        return [subexpr_call], varnames, funcnames
Ejemplo n.º 4
0
 def visit_BoolOp(self, boolop):
     res_var = self.variable()
     expl_list = self.assign(ast.List([], ast.Load()))
     app = ast.Attribute(expl_list, "append", ast.Load())
     is_or = int(isinstance(boolop.op, ast.Or))
     body = save = self.statements
     fail_save = self.on_failure
     levels = len(boolop.values) - 1
     self.push_format_context()
     # Process each operand, short-circuting if needed.
     for i, v in enumerate(boolop.values):
         if i:
             fail_inner = []
             # cond is set in a prior loop iteration below
             self.on_failure.append(ast.If(cond, fail_inner, []))  # noqa
             self.on_failure = fail_inner
         self.push_format_context()
         res, expl = self.visit(v)
         body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
         expl_format = self.pop_format_context(ast.Str(expl))
         call = ast_Call(app, [expl_format], [])
         self.on_failure.append(ast.Expr(call))
         if i < levels:
             cond = res
             if is_or:
                 cond = ast.UnaryOp(ast.Not(), cond)
             inner = []
             self.statements.append(ast.If(cond, inner, []))
             self.statements = body = inner
     self.statements = save
     self.on_failure = fail_save
     expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
     expl = self.pop_format_context(expl_template)
     return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
Ejemplo n.º 5
0
    def translate(self):
        """Compile the template to a Python function."""
        expressions, varnames, funcnames = self.expr.translate()

        argnames = []
        for varname in varnames:
            argnames.append(VARIABLE_PREFIX + varname)
        for funcname in funcnames:
            argnames.append(FUNCTION_PREFIX + funcname)

        func = compile_func(
            argnames,
            [ast.Return(ast.List(expressions, ast.Load()))],
        )

        def wrapper_func(values={}, functions={}):
            args = {}
            for varname in varnames:
                args[VARIABLE_PREFIX + varname] = values[varname]
            for funcname in funcnames:
                args[FUNCTION_PREFIX + funcname] = functions[funcname]
            parts = func(**args)
            return u''.join(parts)

        return wrapper_func
Ejemplo n.º 6
0
def ast_repr(x):
    """Similar to repr(), but returns an AST instead of a String, which when
    evaluated will return the given value."""
    if type(x) in (int, float): return ast.Num(n=x)
    elif type(x) in (str, unicode): return ast.Str(s=x)
    elif type(x) is list: return ast.List(elts=map(ast_repr, x))
    elif type(x) is dict:
        return ast.Dict(keys=map(ast_repr, x.keys()),
                        values=map(ast_repr, x.values()))
    elif type(x) is set:
        return ast.Set(elts=map(ast_repr, x))
    elif type(x) is Literal:
        return x.body
    elif type(x) is Captured:
        return ast.Call(ast.Name(id="Captured"),
                        [x.val, ast_repr(x.name)], [], None, None)
    elif x is None:
        return ast.Name(id="None")
    elif x is True:
        return ast.Name(id="True")
    elif x is False:
        return ast.Name(id="False")
    elif isinstance(x, ast.AST):
        fields = [ast.keyword(a, ast_repr(b)) for a, b in ast.iter_fields(x)]
        return ast.Call(ast.Name(id=x.__class__.__name__), [], fields, None,
                        None)
    raise Exception("Don't know how to ast_repr this: ", x)
Ejemplo n.º 7
0
    def translate(self):
        """Compile the function call."""
        varnames = set()
        funcnames = set([self.ident.encode('utf8')])

        arg_exprs = []
        for arg in self.args:
            subexprs, subvars, subfuncs = arg.translate()
            varnames.update(subvars)
            funcnames.update(subfuncs)

            # Create a subexpression that joins the result components of
            # the arguments.
            arg_exprs.append(
                ex_call(
                    ast.Attribute(ex_literal(u''), b'join', ast.Load()),
                    [
                        ex_call(b'map', [
                            ex_rvalue(b'unicode'),
                            ast.List(subexprs, ast.Load()),
                        ])
                    ],
                ))

        subexpr_call = ex_call(FUNCTION_PREFIX + self.ident.encode('utf8'),
                               arg_exprs)
        return [subexpr_call], varnames, funcnames
Ejemplo n.º 8
0
    def _generate_python_library_ast_node(
        self,
        name: Optional[str] = None,
        globs_path: str = "**/*.py",
        include_extra_dependencies: bool = True,
    ) -> ast.Expr:
        """Generate an AST node for a python_library Pants target

        Args:
            name: Name of the library target. If not provided, no name will be set.
            globs_path: File globs to include in the target. Defaults to everything.
            include_extra_dependencies: Flag for whether the extra dependencies
                specified in the config file should be included. This should usually be
                True except when generating a test library target.

        Returns:
            AST expression node

        """
        keywords = [
            self._get_dependencies_keyword(
                include_extra_dependencies=include_extra_dependencies
            ),
            ast.keyword(arg="sources", value=ast.List(elts=[ast.Str(globs_path)])),
            self._tags_keyword,
        ]
        if name is not None:
            keywords.insert(0, ast.keyword(arg="name", value=ast.Str(name)))
        node = ast.Expr(
            value=ast.Call(
                func=ast.Name(id="python_library"), args=[], keywords=keywords
            )
        )
        return node
Ejemplo n.º 9
0
    def visit_Assert(self, node):
        is_str_mod = False
        if node.msg is not None:
            if isinstance(node.msg, ast.Constant):
                msg = node.msg.value
            elif isinstance(node.msg, ast.Str):
                msg = node.msg.s
            elif self._is_string_mod_args(node.msg):
                # Delay the handling until we call generic_visit() on |node|.
                is_str_mod = True
            else:
                raise ValueError(
                    f"assert info must be constant, not {ast.dump(node.msg)}")
        else:
            import astor
            msg = astor.to_source(node.test)
        self.generic_visit(node)

        extra_args = ast.List(elts=[], ctx=ast.Load())
        if is_str_mod:
            msg, extra_args = self._handle_string_mod_args(node.msg)

        new_node = self.parse_stmt('ti.ti_assert(0, 0, [])')
        new_node.value.args[0] = node.test
        new_node.value.args[1] = self.parse_expr("'{}'".format(msg.strip()))
        new_node.value.args[2] = extra_args
        new_node = ast.copy_location(new_node, node)
        return new_node
Ejemplo n.º 10
0
    def get_module_nodes(self):
        modules = list(
            set(self._field_nodes.keys()) | set(self._type_nodes.keys()))
        result = {}

        for module in modules:
            self.add_import_statement(module, "commercetools", "types")
            self.add_import_statement(module, "marshmallow")

            type_nodes = reorder_class_definitions(self._type_nodes[module])
            global_nodes = [
                ast.Assign(
                    targets=[ast.Name(id="__all__")],
                    value=ast.List(elts=[
                        ast.Str(s=node.name)
                        for node in sorted(type_nodes,
                                           key=operator.attrgetter("name"))
                    ]),
                )
            ]
            all_nodes = (self._import_nodes[module] + global_nodes +
                         self._field_nodes[module] + type_nodes)
            value = ast.Module(body=all_nodes)
            result[module] = value

        result["__init__"] = self.generate_init_module(result.keys())
        return result
Ejemplo n.º 11
0
def obj_to_ast(obj):
    if isinstance(obj, tuple):
        return ast.Tuple(elts=tuple(map(obj_to_ast, obj)))
    elif isinstance(obj, dict):
        k, v = unzip([(obj_to_ast(k), obj_to_ast(v)) for k, v in obj.items()])
        return ast.Dict(k, v)
    elif isinstance(obj, list):
        return ast.List(list(map(obj_to_ast, obj)))
    elif isinstance(obj, type):
        return ast.Name(id=obj.__name__)
    elif isinstance(obj, int):
        return ast.Num(obj)
    elif isinstance(obj, str):
        return ast.Str(obj)
    elif obj is None:
        return ast.NameConstant(None)
    elif isinstance(obj, (typing._GenericAlias, typing._SpecialForm)):
        # TODO: types
        # issue was in pandas, where importing pandas._typing.Axis would
        # resolve module to typing, attempt to do "from typing import Axis"
        return ast.NameConstant(None)
    elif isinstance(obj, float) and math.isinf(obj):
        return parse_expr('float("inf")')
    elif isinstance(obj, bytes):
        return ast.Bytes(s=obj)
    else:
        raise ObjConversionException(f"No converter for {obj}")
Ejemplo n.º 12
0
def convert_tree_to_ssa(tree: ast.AST, defn_env: dict, phi_name: str = "phi"):
    # tree = MoveReturn().visit(tree)
    # tree.body.append(
    #     ast.Return(ast.Name("__magma_ssa_return_value", ast.Load())))
    ssa_visitor = SSAVisitor(phi_name)
    tree = ssa_visitor.visit(tree)
    return_transformer = TransformReturn()
    tree = return_transformer.visit(tree)
    num_return_values = len(ssa_visitor.return_values)
    for i in reversed(range(num_return_values)):
        conds = ssa_visitor.return_values[i]
        name = f"__magma_ssa_return_value_{i}"
        if i == num_return_values - 1 or not conds:
            if isinstance(tree.returns, ast.Tuple):
                tree.body.append(ast.Assign(
                    [ast.Tuple([ast.Name(f"O{i}", ast.Store())
                     for i in range(len(tree.returns.elts))], ast.Store())],
                    ast.Name(name, ast.Load())
                ))
            else:
                tree.body.append(ast.Assign([ast.Name("O", ast.Load)],
                                            ast.Name(name, ast.Load())))
        else:
            cond = conds[-1]
            for c in conds[:-1]:
                c = ast.BinOp(cond, ast.And(), c)
            if isinstance(tree.returns, ast.Tuple):
                for i in range(len(tree.returns.elts)):
                    tree.body.append(ast.Assign(
                        [ast.Name(f"O{i}", ast.Store())],
                        ast.Call(ast.Name(phi_name, ast.Load()), [
                            ast.List([
                                ast.Name(f"O{i}", ast.Load()),
                                ast.Subscript(ast.Name(name, ast.Load()),
                                              ast.Index(ast.Num(i)),
                                              ast.Load())
                            ], ast.Load()),
                            cond], []))
                    )
            else:
                tree.body.append(ast.Assign(
                    [ast.Name("O", ast.Store())],
                    ast.Call(ast.Name(phi_name, ast.Load()), [
                        ast.List([ast.Name("O", ast.Load()), ast.Name(name, ast.Load())],
                                 ast.Load()), cond], []))
                )
    return tree, ssa_visitor.args
Ejemplo n.º 13
0
    def __init__(self, initial_values, variable_names, states, derivatives, system_tag=""):
        """
        initial_values - initial values of global variables array. Array should be ordered in  such way
         that all the derivatives are located in the tail.
        variable_names - dictionary
        states - states
        derivatives -  derivatives
        """
        self.body_init_set_var = [ast.Assign(targets=[GLOBAL_ARRAY],
                                             value=ast.Call(func=ast.Name(id='np.array',
                                                                          ctx=ast.Load()),
                                                            args=[ast.List(
                                                                elts=[ast.Constant(value=v) for v in initial_values],
                                                                ctx=ast.Load())],
                                                            keywords=[]
                                                            ), lineno=0)]

        self.kernel_function = []
        self.variable_names = variable_names
        self.states = states
        self.derivatives = derivatives
        self.functions = []
        self.defined_functions = []
        self.body = []
        self.kernel_filename = LISTING_FILEPATH + system_tag + LISTINGFILENAME

        self.read_args_section = [ast.Expr(value=ast.Call(func=ast.Name(id='np.put'),
                                                          args=[GLOBAL_ARRAY,
                                                                ast.List(
                                                                    elts=[ast.Constant(value=v) for v in
                                                                          [self.variable_names[x] for x in
                                                                           self.states]],
                                                                    ctx=ast.Load()),
                                                                ast.Name(id='states', ctx=ast.Store())
                                                                ],
                                                          keywords=[]))]

        self.return_section = [ast.Return(
            value=ast.Call(func=ast.Name(id='np.take'), args=[GLOBAL_ARRAY,
                                                              ast.List(
                                                                  elts=[ast.Constant(value=v) for v in
                                                                        [self.variable_names[x] for x in
                                                                         self.derivatives]],
                                                                  ctx=ast.Load())
                                                              ],
                           keywords=[]))]
Ejemplo n.º 14
0
    def parse(self, func):
        """Function decorator, returning a correct method from a pseudo-Python
        one"""

        # Get the function AST
        parsed = ast.parse(inspect.getsource(func))
        fc_ast = parsed.body[0]
        argument_names = [name.id for name in fc_ast.args.args]

        # Init local cache
        self._local_ctx = {}

        # Translate (blocks[0][0] is the current instr)
        blocks, body = self._parse_body(fc_ast.body, argument_names)

        # Build the new function
        fc_ast.args.args[0:0] = [ast.Name(id='ir', ctx=ast.Param()),
                                 ast.Name(id='instr', ctx=ast.Param())]
        cur_instr = blocks[0][0]
        if len(blocks[-1][0]) == 0:
            ## Last block can be empty
            blocks.pop()
        other_blocks = blocks[1:]
        body.append(ast.Return(value=ast.Tuple(elts=[ast.List(elts=cur_instr,
                                                              ctx=ast.Load()),
                                                     ast.List(elts=other_blocks,
                                                              ctx=ast.Load())],
                                               ctx=ast.Load())))

        ret = ast.Module([ast.FunctionDef(name=fc_ast.name,
                                          args=fc_ast.args,
                                          body=body,
                                          decorator_list=[])])

        # To display the generated function, use codegen.to_source
        # codegen: https://github.com/andreif/codegen

        # Compile according to the context
        fixed = ast.fix_missing_locations(ret)
        codeobj = compile(fixed, '<string>', 'exec')
        ctx = self._ctx.copy()
        eval(codeobj, ctx)

        # Get the function back
        self._functions[fc_ast.name] = ctx[fc_ast.name]
        return ctx[fc_ast.name]
Ejemplo n.º 15
0
 def to_ast(self):
     return ast.Call(func=ast.Name(id='NamedParameters', ctx=ast.Load()), 
                     args=[ast.List(elts=[ast.Tuple(elts=[ast.Str(s=name),
                                                          ty.to_ast()],
                                                    ctx=ast.Load())\
                                              for name, ty in self.parameters],
                                    ctx=ast.Load())],
                     keywords=[], starargs=None, kwargs=None)
Ejemplo n.º 16
0
 def visit_DictComp(self, node):
     # this is a quickfix to match visit_AnyComp signature
     # potential source of improvement there!
     node.elt = ast.List(
         [ast.Tuple([node.key, node.value], ast.Load())],
         ast.Load()
         )
     return self.visit_AnyComp(node, "dict", "__dispatch__", "update")
Ejemplo n.º 17
0
    def test_simple_enumerated_list(self):
        inputData = "[1, 2, 3]"
        expected = ast.Expr(
            ast.List(
                [ast.Num(1), ast.Num(2), ast.Num(3)], None))
        result = transpile(inputData)

        self.assertTrue(compare_ast(result, expected))
Ejemplo n.º 18
0
 def MakeVector(self, mv):
     result = ast.parse('__np__.array()', mode='eval').body
     result.args = [
         ast.List(elts=[self(el) for el in mv.elems],
                  ctx=ast.Load(),
                  **_linearg)
     ]
     return result
Ejemplo n.º 19
0
 def _convert_value(self, value):
     if isinstance(value, bool):
         return ast.Str(str(value) if value else '')
     elif isinstance(value, list):
         return ast.List(elts=list(map(self._convert_value, value)),
                         ctx=ast.Load())
     else:
         return ast.Str(str(value))
Ejemplo n.º 20
0
 def to_ast(self, lineno: int, col_offset: int) -> ast.expr:
     return ast.List(elts=[
         ast.Str(s=k, lineno=lineno, col_offset=col_offset)
         for k in self.members
     ],
                     lineno=lineno,
                     col_offset=col_offset,
                     ctx=ast.Load())
Ejemplo n.º 21
0
    def mathTransform(self, attribute, args):

        # operations from the math python module or builtin operations that exist in JavaScript Math:
        if attribute in self.directMathOperations:
            func = ast.Attribute(value=ast.Name(id='Math', ctx=ast.Load()),
                                 attr=attribute,
                                 ctx=ast.Load())

            return ast.Call(func=func, args=args, keywords=[])

        # substitutable operations, e.g. a = sum(b,c) => a = [b,c].reduce( function(x,y) { return x+y: })
        elif attribute in self.subtitutableOperations:
            # a = sum(b,c) => a = [b,c].reduce( function(x,y) { return x+y: })
            if attribute == 'sum':
                func = ast.Attribute(value=ast.List(elts=args, ctx=ast.Load()),
                                     attr='reduce',
                                     ctx=ast.Load())

                args = [
                    ast.Call(
                        func=ast.Name(id='JS', ctx=ast.Load()),
                        args=[ast.Str(s=' function(x,y) { return x+y; }')],
                        keywords=[])
                ]

                return ast.Call(func=func, args=args, keywords=[])

            # randint(a,b) => Math.floor(Math.random() * (b - a + 1)) + a
            elif attribute == 'randint':

                left = ast.Call(
                    func=ast.Attribute(value=ast.Name(id='Math',
                                                      ctx=ast.Load()),
                                       attr='floor',
                                       ctx=ast.Load()),
                    args=[
                        ast.BinOp(left=ast.Call(func=ast.Attribute(
                            value=ast.Name(id='Math', ctx=ast.Load()),
                            attr='random',
                            ctx=ast.Load()),
                                                args=[],
                                                keywords=[]),
                                  op=ast.Mult(),
                                  right=ast.BinOp(left=ast.BinOp(
                                      left=args[1],
                                      op=ast.Sub(),
                                      right=args[0]),
                                                  op=ast.Add(),
                                                  right=ast.Num(n=1)))
                    ],
                    keywords=[])

                right = args[0]

                return ast.BinOp(left=left, op=ast.Add(), right=right)

        else:
            return None
Ejemplo n.º 22
0
    def build_Compare(ctx, node):
        operands = build_exprs(ctx, [node.left] + list(node.comparators))
        operators = []
        for i in range(len(node.ops)):
            if isinstance(node.ops[i], ast.Lt):
                op_str = 'Lt'
            elif isinstance(node.ops[i], ast.LtE):
                op_str = 'LtE'
            elif isinstance(node.ops[i], ast.Gt):
                op_str = 'Gt'
            elif isinstance(node.ops[i], ast.GtE):
                op_str = 'GtE'
            elif isinstance(node.ops[i], ast.Eq):
                op_str = 'Eq'
            elif isinstance(node.ops[i], ast.NotEq):
                op_str = 'NotEq'
            elif isinstance(node.ops[i], ast.In):
                raise TaichiSyntaxError(
                    '"in" is not supported in Taichi kernels.')
            elif isinstance(node.ops[i], ast.NotIn):
                raise TaichiSyntaxError(
                    '"not in" is not supported in Taichi kernels.')
            elif isinstance(node.ops[i], ast.Is):
                raise TaichiSyntaxError(
                    '"is" is not supported in Taichi kernels.')
            elif isinstance(node.ops[i], ast.IsNot):
                raise TaichiSyntaxError(
                    '"is not" is not supported in Taichi kernels.')
            else:
                raise Exception(f'Unknown operator {node.ops[i]}')
            operators += [
                ast.copy_location(ast.Str(s=op_str, kind=None), node)
            ]

        call = ast.Call(
            func=parse_expr('ti.chain_compare'),
            args=[
                ast.copy_location(ast.List(elts=operands, ctx=ast.Load()),
                                  node),
                ast.copy_location(ast.List(elts=operators, ctx=ast.Load()),
                                  node)
            ],
            keywords=[])
        call = ast.copy_location(call, node)
        return call
Ejemplo n.º 23
0
    def parameterListBuilder(self, parameter_list):
        ast_list = []
        for parameter in parameter_list:
            if parameter:
                ast_list.append(ast.Num(n=parameter))
            else:
                ast_list.append(ast.NameConstant(value=None))

        return ast.List(elts=ast_list)
Ejemplo n.º 24
0
 def p_expr_hexstr(self, p):
     '''expr : HEXSTR'''
     s = p[1].replace('\'', '')
     try:
         _ = int(s, 16)
     except ValueError:
         raise Exception('Invalid hex literal.')
     byte_arr = [s[i:i + 2] for i in range(0, len(s), 2)]
     p[0] = ast.List(elts=byte_arr, ctx=ast.Store())
Ejemplo n.º 25
0
    def composite(self, children):
        fields = []
        for child in children:
            if isinstance(child, lark.Token):
                if child.type == 'NODE_TYPE':
                    node_type = child.value
                else:
                    pass
            elif isinstance(child, ast.AST):
                fields.append(child)
            else:
                pass

        if node_type == 'list':
            return ast.List(elts=fields, ctx=ast.Load())

        elif node_type == 'attr':
            if len(fields) != 2:
                raise SyntaxError('Attribute node must have two fields; found ' + len(fields))
            if not isinstance(fields[1], ast.Str):
                raise SyntaxError('Attribute name must be a string; found ' + type(fields[1]))
            return ast.Attribute(value=fields[0], attr=fields[1].s, ctx=ast.Load())

        elif node_type == 'call':
            if len(fields) < 1:
                raise SyntaxError('Call node must have at least one field; found ' + len(fields))
            return ast.Call(func=fields[0], args=fields[1:], keywords=[])

        elif node_type == 'lambda':
            if len(fields) != 2:
                raise SyntaxError('Lambda node must have two fields; found ' + len(fields))
            if not isinstance(fields[0], ast.List):
                raise SyntaxError('Lambda arguments must be in a list; found ' + type(fields[0]))
            for arg in fields[0].elts:
                if not isinstance(arg, ast.Name):
                    raise SyntaxError('Lambda arguments must variable names; found ' + type(arg))
            return ast.Lambda(args=ast.arguments(args=[ast.arg(arg=name.id, annotation=None)
                                                       for name in fields[0].elts],
                                                 vararg=None,
                                                 kwonlyargs=[],
                                                 kw_defaults=[],
                                                 kwarg=None,
                                                 defaults=[]),
                              body=fields[1])

        elif node_type == 'Select':
            if len(fields) != 2:
                raise SyntaxError('Select node must have two fields; found ' + len(fields))
            if not isinstance(fields[1], ast.Lambda):
                raise SyntaxError('Select selector must be a lambda; found ' + type(fields[1]))
            if len(fields[1].args.args) != 1:
                raise SyntaxError('Select selector must have exactly one argument; found '
                                  + len(fields[1].args.args))
            return linq_util.Select(source=fields[0], selector=fields[1])

        else:
            raise SyntaxError('Unknown composite node type: ' + node_type)
Ejemplo n.º 26
0
    def test_withIterNodes(self):
        nodes = ast.If(
            ast.Call(ast.Name('toto', ast.Load()), [ast.List([], ast.Load())],
                     [], None, None),
            [
                ast.Print(
                    None,
                    ast.Call(ast.Name('toto', ast.Load()),
                             [ast.List([], ast.Load())], [], None, None),
                    False),
            ],
            [],
        )
        waitedRes = 'If Call Name Load List Load Print Call Name Load List Load'.split(
            ' ')

        iterRes = [n.__class__.__name__ for n in iter_nodes(nodes)]
        self.assertEquals(waitedRes, iterRes)
Ejemplo n.º 27
0
 def test_capture_nested(self):
     ast_node = ast.List(elts=[
         ast.Constant(value=1),
         ast.Constant(value=2),
         ast.Constant(value=3)
     ])
     pattern_node = ast.List(elts=[
         ast.Constant(value=anm.Capture("first")),
         ast.Constant(value=anm.Capture("second")),
         ast.Constant(value=anm.Capture("third")),
     ])
     captures = {}
     matches = anm.match(ast_node, pattern_node, captures)
     assert matches
     assert captures["first"] == 1
     assert captures["second"] == 2
     assert captures["third"] == 3
     pass
Ejemplo n.º 28
0
def eval_expro(expr, env, value, depth=0, maxdepth=3):
    # logger.debug("Evaluating expr {} to {} with env {}".format(expr, value, env))
    uuid = str(uuid4())[:4]
    if isinstance(expr, ast.AST):
        logger.info("Found AST for expr -> {}".format(
            ast_dump_if_possible(expr)))
    if isinstance(value, ast.AST):
        logger.info("Found AST for value -> {}".format(
            ast_dump_if_possible(value)))

    if depth >= maxdepth:
        return fail
    # fmt: off
    return conde(
        (eq(expr, ast.Name(id=var('name_' + uuid), ctx=ast.Load())),
         lookupo(var('name_' + uuid), env, value)),
        # (lany(
        #     typeo(value, int),
        #     typeo(value, str),
        #  ),
        #  eq(expr, ast.Constant(value=value)),),
        (eq(expr, ast.Str(s=var('str_e_' + uuid))), typeo(
            value, str), eq(var('str_e_' + uuid), value)),
        (eq(expr, ast.Num(n=value)), membero(value, [_ for _ in range(5)])),
        (eq(
            expr,
            ast.BinOp(left=var('e1_' + uuid),
                      op=var('op_e_' + uuid),
                      right=var('e2_' + uuid))), typeo(var('v1_' + uuid), int),
         typeo(var('v2_' + uuid), int),
         eval_expro(var('e1_' + uuid), env, var('v1_' + uuid), depth + 1,
                    maxdepth),
         eval_expro(var('e2_' + uuid), env, var('v2_' + uuid), depth + 1,
                    maxdepth),
         eval_opo(var('op_e_' + uuid), var('op_v_' + uuid), var('v1_' + uuid),
                  var('v2_' + uuid), value),
         binopo(var('v1_' + uuid),
                var('v2_' + uuid),
                value,
                op=var('op_v_' + uuid))),

        # Lists
        (eq(expr, ast.List(elts=var("list_elements_" + uuid), ctx=ast.Load())),
         eval_expr_listo(var("list_elements_" + uuid), env, value, depth,
                         maxdepth)),

        # Functions
        (eq(expr, ast.Lambda(body=var('body_' + uuid),
                             args=[])), typeo(value, FunctionType),
         eval_expro(var('body_' + uuid), env, var('body_v_' + uuid), depth + 1,
                    maxdepth), eq(lambda: var('body_v_' + uuid), value)),
        (eq(expr, ast.Call(func=var('func_' + uuid), args=[], keywords=[])),
         typeo(var('func_v_' + uuid), FunctionType),
         eval_expro(var('func_' + uuid), env, var('func_v_' + uuid), depth + 1,
                    maxdepth), applyo(var('func_v_' + uuid), [], value)),
    )
Ejemplo n.º 29
0
def compile_terminal(sexp: List, closure: Dict) -> ast.AST:
    """
    Compiles primitive type variable (language built-in) to AST node.

    `closure` contains name bindings for target function. Variables of
    non-primitive (built-in) types (without corresponding AST node) 
    are given a unique random name, converted to ast.Name and stored
    in closure for the target function.
    """
    if type(sexp) is bool:
        return ast.NameConstant(value=sexp), closure

    elif type(sexp) in (int, float, complex):
        return ast.Num(n=sexp), closure

    elif type(sexp) is str:
        return ast.Str(s=sexp), closure

    elif type(sexp) is bytes:
        return ast.Bytes(s=sexp), closure

    elif type(sexp) is list:
        elts = []
        for e in sexp:
            e, closure = compile_terminal(e, closure)
            elts.append(e)
        return ast.List(elts=elts, ctx=ast.Load()), closure

    elif type(sexp) is tuple:
        elts = []
        for e in sexp:
            e, closure = compile_terminal(e, closure)
            elts.append(e)
        return ast.Tuple(elts=elts, ctx=ast.Load()), closure

    elif type(sexp) is dict:
        keys, values = [], []
        for k, v in sexp.items():
            k, closure = compile_terminal(k, closure)
            v, closure = compile_terminal(v, closure)
            keys.append(k)
            values.append(v)
        return ast.Dict(keys=keys, values=values), closure

    elif type(sexp) is set:
        elts = []
        for e in sexp:
            e, closure = compile_terminal(e, closure)
            elts.append(e)
        return ast.Set(elts=elts), closure

    else:
        # Generate random name and store variable in closure.
        name = '_%s' % uuid.uuid4().hex
        closure[name] = sexp
        return ast.Name(id=name, ctx=ast.Load()), closure
Ejemplo n.º 30
0
 def visit_IfExp(self, node):
     if not hasattr(node, "orelse"):
         raise NotImplementedError("If without else")
     node.body = self.visit(node.body)
     node.orelse = self.visit(node.orelse)
     return ast.Call(
         ast.Name("phi", ast.Load()),
         [ast.List([node.orelse, node.body],
                   ast.Load()), node.test],
         [])