Ejemplo n.º 1
0
def operator(mod):
	op = ast.Add()
	if mod == 'or': op = ast.Or()
	if mod == '|': op = ast.Or()
	if mod == '||': op = ast.Or()
	if mod == 'and': op = ast.And()
	if mod == '&': op = ast.And()
	if mod == '&&': op = ast.And()
	if mod == 'plus': op = ast.Add()
	if mod == '+': op = ast.Add()
	if mod == '-': op = ast.Sub()
	if mod == 'minus': op = ast.Sub()
	if mod == 'times': op = ast.Mult()
	if mod == '*': op = ast.Mult()
	if mod == '**': op = ast.Pow()
	if mod == 'divide': op = ast.Div()
	if mod == 'divided': op = ast.Div()
	if mod == 'divided by': op = ast.Div()
	if mod == '/': op = ast.Div()
	if mod == '//': op = ast.FloorDiv()
	if mod == 'floor div': op = ast.FloorDiv()
	if mod == '%': op = ast.Mod()
	if mod == 'mod': op = ast.Mod()
	if mod == 'modulus': op = ast.Mod()
	if mod == 'modulo': op = ast.Mod()
	if mod == '^': op = ast.BitXor()
	if mod == 'xor': op = ast.BitXor()
	if mod == '<<': op = ast.LShift()
	if mod == '>>': op = ast.RShift()
	return op
Ejemplo n.º 2
0
def binop_action(s, loc, tokens):
    node = tokens[0]
    for op_char, right in tokens[1:]:
        if op_char == '+':
            op = ast.Add()
        elif op_char == '-':
            op = ast.Sub()
        elif op_char == '*':
            op = ast.Mult()
        elif op_char == '/':
            op = ast.Div()
        elif op_char == '%':
            op = ast.Mod()
        elif op_char == '<<':
            op = ast.LShift()
        elif op_char == '>>':
            op = ast.RShift()
        elif op_char == '&':
            op = ast.BitAnd()
        elif op_char == '^':
            op = ast.BitXor()
        else:  # op_char == '|':
            op = ast.BitOr()

        node = ast.BinOp(left=node, op=op, right=right, lineno=1, col_offset=0)

    return node
Ejemplo n.º 3
0
    def get_bin_op(self, s):
        """Get the BinOp class for s."""
        op = None
        if s == '+':
            op = ast.Add()
        elif s == '-':
            op = ast.Sub()
        elif s == '*':
            op = ast.Mult()
        elif s == '/':
            op = ast.Div()
        elif s == '%':
            op = ast.Mod()
        elif s == '<<':
            op = ast.LShift()
        elif s == '>>':
            op = ast.RShift()

        elif s == '&':
            op = ast.BitAnd()
        elif s == '^':
            op = ast.BitXor()
        elif s == '|':
            op = ast.BitOr()

        return op
Ejemplo n.º 4
0
    def __build_unconditional_arg_check(self, argname, argtype):

        presence_check = ast.Call(
            func=ast.Name(id='isinstance', ctx=ast.Load()),
            args=[ast.Name(id=argname, ctx=ast.Load()), argtype],
            keywords=[],
            lineno=self.__get_line())

        types = [t.id for t in argtype.elts]
        check_message = ast.BinOp(left=ast.Str(
            s='Argument \'{}\' must be of type \'{}\'. Received type: \'%s\''.
            format(argname, types)),
                                  op=ast.Mod(),
                                  right=ast.Call(func=ast.Name(id='type',
                                                               ctx=ast.Load()),
                                                 args=[
                                                     ast.Name(id=argname,
                                                              ctx=ast.Load())
                                                 ],
                                                 keywords=[]),
                                  lineno=self.__get_line())

        new_ret = ast.Assert(test=presence_check,
                             msg=check_message,
                             lineno=self.__get_line())

        return new_ret
    def __init__(self, base_node):
        BaseMutator.__init__(self, base_node)
        self.original_bin_op = base_node.op

        if type(base_node.op) in [
                ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod, ast.Pow
        ]:
            if type(base_node.op) is ast.Add:
                # Don't perform the mutation for string concatenation (e.g. 'string' + 'concat')
                if (type(base_node.left) is not ast.Str) and (type(
                        base_node.right) is not ast.Str):
                    self.mutations.append({"op": ast.Sub()})

            if type(base_node.op) is ast.Sub:
                self.mutations.append({"op": ast.Add()})

            if type(base_node.op) is ast.Mult:
                # Don't perform the mutation for string repetition (e.g. 'string' * 50)
                if (type(base_node.left) is not ast.Str) and (type(
                        base_node.right) is not ast.Str):
                    self.mutations.append({"op": ast.Div()})

            if type(base_node.op) is ast.Div:
                self.mutations.append({"op": ast.Mult()})

            if type(base_node.op) is ast.Mod:
                # Don't perform the mutation for string format (e.g. 'strings are %s' % 'cool')
                if (type(base_node.left) is not ast.Str) and (type(
                        base_node.right) is not ast.Str):
                    self.mutations.append({"op": ast.Pow()})

            if type(base_node.op) is ast.Pow:
                self.mutations.append({"op": ast.Mod()})
Ejemplo n.º 6
0
    def _create_repr_method(self):
        """Create the __repr__ method.

            def __repr__(self) -> str:
                return ('Attribute(name=%r, value=%r)' % (self.name, self.value))

        """
        node = ast.FunctionDef(
            name="__repr__",
            args=ast.arguments(
                args=[ast.arg(arg="self", annotation=None)],
                vararg=None,
                kwonlyargs=[],
                kw_defaults=[],
                kwarg=None,
                defaults=[],
            ),
            body=[],
            decorator_list=[],
            returns=ast.Name(id="str"),
        )
        node.body.append(
            ast.Return(value=ast.BinOp(
                left=ast.Str(s="%s(%s)" % (
                    self.resource.name,
                    ", ".join(f"{attr}=%r" for attr in self.attribute_names),
                )),
                op=ast.Mod(),
                right=ast.Tuple(elts=[
                    ast.Name(id=f"self.{attr}")
                    for attr in self.attribute_names
                ]),
            )))
        return node
 def visit_Operator(self, node: Operator, *args, **kwargs) -> C.operator:
     if node == Operator.Add:
         return C.Add()
     elif node == Operator.Sub:
         return C.Sub()
     elif node == Operator.Mult:
         return C.Mult()
     elif node == Operator.MatMult:
         return C.MatMult()
     elif node == Operator.Div:
         return C.Div()
     elif node == Operator.Mod:
         return C.Mod()
     elif node == Operator.Pow:
         return C.Pow()
     elif node == Operator.LShift:
         return C.LShift()
     elif node == Operator.RShift:
         return C.RShift()
     elif node == Operator.BitOr:
         return C.BitOr()
     elif node == Operator.BitXor:
         return C.BitXor()
     elif node == Operator.BitAnd:
         return C.BitAnd()
     elif node == Operator.FloorDiv:
         return C.FloorDiv()
     else:
         raise Exception(f'unknown Operator {node!r}')
Ejemplo n.º 8
0
	def __build_unconditional_arg_check(self, argname, argtype):
		# checker_str = "assert isinstance({argname}, {typetuple}), \"Argument {argname} must be of type {typetuple}. Received type: %s\" % type({argname})".format(
		# 		argname = argname,
		# 		typetuple = argtype,
		# 	)
		# checker = ast.parse(checker_str)
		# old_ret = checker.body.pop()

		presence_check = ast.Call(func = ast.Name(id='isinstance', ctx=ast.Load()),
				args         = [ast.Name(id=argname, ctx=ast.Load()), argtype],
				keywords     = [],
				lineno       = self.__get_line())

		check_message = ast.BinOp(
				left         = ast.Str(s='Argument {} must be of type ({}). Received type: %s'.format(argname, argtype)),
				op           = ast.Mod(),
				right        = ast.Call(func=ast.Name(id='type', ctx=ast.Load()), args=[ast.Name(id=argname, ctx=ast.Load())], keywords=[]),
				lineno       = self.__get_line())

		new_ret = ast.Assert(
			test         = presence_check,
			msg          = check_message,
			lineno       = self.__get_line())


		return new_ret
Ejemplo n.º 9
0
 def visit_Str(self, node):
     replacements = re.findall(r'#{[^}]+}', node.s)
     if not replacements:
         return node
     s = node.s
     for rep in replacements:
         s = s.replace(rep, '%s')
     elements = [ast.parse(rep[2:-1]).body[0].value for rep in replacements]
     node = ast.BinOp(ast.Str(s), ast.Mod(), make_tuple(*elements))
     return node
Ejemplo n.º 10
0
 def pop_format_context(self, expl_expr):
     current = self.stack.pop()
     if self.stack:
         self.explanation_specifiers = self.stack[-1]
     keys = [ast.Str(key) for key in current.keys()]
     format_dict = ast.Dict(keys, list(current.values()))
     form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
     name = "@py_format" + str(next(self.variable_counter))
     self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
     return ast.Name(name, ast.Load())
Ejemplo n.º 11
0
def eval_opo(op, value, v1, v2, v):
    # Extra args for future use
    # fmt: off
    return conde(
        (eq(op, ast.Add()), eq(value, add)),
        (eq(op, ast.Sub()), eq(value, sub)),
        (eq(op, ast.Mult()), eq(value, mul)),
        (
            eq(op, ast.Mod()),
            neq(v2, 0),  # Prevent division by zero
            eq(value, mod)),
    )
 def test_scalar_bin_op_init(self):
     ScalarBinOp(self.constant, ast.Add(), self.constant)
     ScalarBinOp(self.output_element, ast.Add(), self.neighbor)
     ScalarBinOp(self.output_element, ast.Sub(), self.neighbor)
     ScalarBinOp(self.output_element, ast.Mult(), self.neighbor)
     ScalarBinOp(self.output_element, ast.Div(), self.neighbor)
     ScalarBinOp(self.output_element, ast.FloorDiv(), self.neighbor)
     ScalarBinOp(self.output_element, ast.Mod(), self.neighbor)
     for op in [
             ast.Mod, ast.Pow, ast.LShift, ast.RShift, ast.BitOr,
             ast.BitXor, ast.BitAnd
     ]:
         with self.assertRaises(AssertionError):
             ScalarBinOp(self.output_element, op, self.neighbor)
Ejemplo n.º 13
0
    def visit_UnaryOp(self, node):
        'Same idea as visit_BinOp'
        if node in self.constexpr:
            # evaluation
            fake_node = ast.Expression(
                ast.BinOp(node, ast.Mod(), ast.Num(self.mod)))
            ast.fix_missing_locations(fake_node)
            code = compile(fake_node, '<constant folding>', 'eval')
            obj_env = globals().copy()
            exec code in obj_env

            value = eval(code, obj_env)
            new_node = ast.Num(value)
            return new_node
        else:
            return self.generic_visit(node)
Ejemplo n.º 14
0
def operator_equals(mod):
	op = ast.Add()
	if mod == '|=': op = ast.Or()
	if mod == '||=': op = ast.Or()
	if mod == '&=': op = ast.And()
	if mod == '&&=': op = ast.And()
	if mod == '+=': op = ast.Add()
	if mod == '-=': op = ast.Sub()
	if mod == '*=': op = ast.Mult()
	if mod == '**=': op = ast.Pow()
	if mod == '/=': op = ast.Div()
	if mod == '//=': op = ast.FloorDiv()
	if mod == '%=': op = ast.Mod()
	if mod == '^=': op = ast.BitXor()
	if mod == '<<': op = ast.LShift()
	if mod == '>>': op = ast.RShift()
	return op
Ejemplo n.º 15
0
 def create_term_node(self, term):
     last_factor_index = len(term.factors)
     node = self.to_node(term.factors[0])
     if last_factor_index == 0:
         return node
     for i in range(1, last_factor_index):
         if term.operators[i - 1] in ["*", "times"]:
             node = ast.BinOp(node, ast.Mult(),
                              self.to_node(term.factors[i]))
         elif term.operators[i - 1] in ["/", "divided by"]:
             node = ast.BinOp(node, ast.Div(),
                              self.to_node(term.factors[i]))
         elif term.operators[i - 1] in ["%", "modulo"]:
             node = ast.BinOp(node, ast.Mod(),
                              self.to_node(term.factors[i]))
         else:
             raise
     return node
Ejemplo n.º 16
0
    def pop_format_context(self, expl_expr):
        """Format the %-formatted string with current format context.

        The expl_expr should be an ast.Str instance constructed from
        the %-placeholders created by .explanation_param().  This will
        add the required code to format said string to .on_failure and
        return the ast.Name instance of the formatted string.

        """
        current = self.stack.pop()
        if self.stack:
            self.explanation_specifiers = self.stack[-1]
        keys = [ast.Str(key) for key in current.keys()]
        format_dict = ast.Dict(keys, list(current.values()))
        form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
        name = "@py_format" + str(next(self.variable_counter))
        self.on_failure.append(ast.Assign([ast.Name(name, ast.Store())], form))
        return ast.Name(name, ast.Load())
Ejemplo n.º 17
0
 def test_for_expr_args(self):
     start = ast.BinOp(ast.Num(2), ast.Add(), ast.Num(3))
     stop = ast.BinOp(ast.Num(4), ast.Mult(), ast.Num(10))
     step = ast.BinOp(ast.Num(3), ast.Mod(), ast.Num(5))
     py_ast = ast.For(
         ast.Name("i", ast.Load()),
         ast.Call(ast.Name("range", ast.Load()), [start, stop, step], [],
                  None, None),
         [ast.Name("foo", ast.Load())],
         [],
     )
     i = SymbolRef("i", Long())
     c_ast = For(
         Assign(i, Add(Constant(2), Constant(3))),
         Lt(i.copy(), Mul(Constant(4), Constant(10))),
         AddAssign(i.copy(), Mod(Constant(3), Constant(5))),
         [SymbolRef("foo")],
     )
     self._check(py_ast, c_ast)
Ejemplo n.º 18
0
 def to_node(self):
     node = self.left.to_node()
     if len(self.operator) == 0:
         return node
     else:
         for i in range(len(self.right)):
             if self.operator[i] in ['*', 'times']:
                 node = ast.BinOp(node, ast.Mult(), self.right[i].to_node())
             elif self.operator[i] in ['/', 'divided by']:
                 node = ast.BinOp(node, ast.Div(), self.right[i].to_node())
             elif self.operator[i] in ['%', 'modulo']:
                 node = ast.BinOp(node, ast.Mod(), self.right[i].to_node())
             elif self.operator[i] == '@':
                 node = ast.BinOp(node, ast.MatMult(),
                                  self.right[i].to_node())
             elif self.operator[i] == '//':
                 node = ast.BinOp(node, ast.FloorDiv(),
                                  self.right[i].to_node())
         return node
Ejemplo n.º 19
0
    def __build_conditional_arg_check(self, argname, argtype):

        target_value = ast.Subscript(value=ast.Name(id='kwargs',
                                                    ctx=ast.Load()),
                                     slice=ast.Index(ast.Str(s=argname)),
                                     ctx=ast.Load())

        presence_check = ast.Call(func=ast.Name(id='isinstance',
                                                ctx=ast.Load()),
                                  args=[target_value, argtype],
                                  keywords=[],
                                  lineno=self.__get_line())

        # Assumes that argtype is a ast.Tuple of ast.Name items
        types = [t.id for t in argtype.elts]

        check_message = ast.BinOp(left=ast.Str(
            s='Optional argument \'{}\' must be of type \'{}\'. Received type: \'%s\''
            .format(argname, types)),
                                  op=ast.Mod(),
                                  right=ast.Call(func=ast.Name(id='type',
                                                               ctx=ast.Load()),
                                                 args=[target_value],
                                                 keywords=[]),
                                  lineno=self.__get_line())

        assert_check = ast.Assert(test=presence_check,
                                  msg=check_message,
                                  lineno=self.__get_line())

        check_body = [assert_check]

        check = ast.Compare(
            left=ast.Str(s=argname, ctx=ast.Load()),
            ops=[ast.In()],
            comparators=[ast.Name(id='kwargs', ctx=ast.Load())])

        new_ret = ast.If(test=check,
                         body=check_body,
                         orelse=[],
                         lineno=self.__get_line())

        return new_ret
Ejemplo n.º 20
0
def resolve_value(value, scope):
    if isinstance(value, EId):
        node = ast.Name(id=value.v, ctx=ast.Load())
    elif isinstance(value, EInt):
        node = ast.Num(n=value.v)
    elif isinstance(value, EList):
        lst = [resolve_value(a, scope) for a in value.v]
        node = ast.List(elts=lst, ctx=ast.Load())
    elif isinstance(value, EOp):
        lft, rgt = value.v
        lft = resolve_value(lft, scope)
        rgt = resolve_value(rgt, scope)

        operators = {
            '+': ast.Add(),
            '-': ast.Sub(),
            '*': ast.Mult(),
            '/': ast.Div(),
            '%': ast.Mod(),
        }

        node = ast.BinOp(left=lft, right=rgt, op=operators[value.t])
    elif isinstance(value, ECompare):
        lft, rgt = value.v
        lft = resolve_value(lft, scope)
        rgt = resolve_value(rgt, scope)

        operators = {
            '<': ast.Lt(),
            '>': ast.Gt(),
            '<=': ast.LtE(),
            '>=': ast.GtE(),
            '==': ast.Eq(),
        }

        node = ast.Compare(left=lft,
                           ops=[operators[value.t]],
                           comparators=[rgt])

    return ast.fix_missing_locations(node)
Ejemplo n.º 21
0
def BinOp(draw, expression) -> ast.BinOp:
    op = draw(
        sampled_from([
            ast.Add(),
            ast.Sub(),
            ast.Mult(),
            ast.Div(),
            ast.FloorDiv(),
            ast.Mod(),
            ast.Pow(),
            ast.LShift(),
            ast.RShift(),
            ast.BitOr(),
            ast.BitXor(),
            ast.BitOr(),
            ast.BitAnd(),
            ast.MatMult()
        ]))

    le = draw(lists(expression, min_size=2, max_size=2))

    return ast.BinOp(le[0], op, le[1])
Ejemplo n.º 22
0
def AugAssign(draw):
    op = draw(
        sampled_from([
            ast.Add(),
            ast.Sub(),
            ast.Mult(),
            ast.Div(),
            ast.FloorDiv(),
            ast.Mod(),
            ast.Pow(),
            ast.LShift(),
            ast.RShift(),
            ast.BitOr(),
            ast.BitXor(),
            ast.BitOr(),
            ast.BitAnd(),
            ast.MatMult()
        ]))

    return ast.AugAssign(target=draw(Name(ast.Store)),
                         op=op,
                         value=draw(expression()))
Ejemplo n.º 23
0
 "divided with": ast.Div(),
 "divided by": ast.Div(),
 "divide": ast.Div(),
 "divide with": ast.Div(),
 "divide by": ast.Div(),
 "xor": ast.BitXor(),
 # "^": ast.BitXor(),
 "^": ast.Pow(),
 "^^": ast.Pow(),
 "**": ast.Pow(),
 "pow": ast.Pow(),
 "power": ast.Pow(),
 "to the": ast.Pow(),
 "to the power": ast.Pow(),
 "to the power of": ast.Pow(),
 "%": ast.Mod(),
 "mod": ast.Mod(),
 "modulo": ast.Mod(),
 "!": ast.Not(),
 "not": ast.Not(),
 "&": ast.And(),  # BitAnd ENGLISH: a & b ~== a and b
 "&&": ast.And(),
 "and": ast.And(),
 "|": ast.BitOr(),
 "||": ast.Or(),
 "or": ast.Or(),
 "does not equal": ast.NotEq(),
 "doesn't equal": ast.NotEq(),
 "not equal": ast.NotEq(),
 "is not": ast.NotEq(),
 "isn't": ast.NotEq(),
Ejemplo n.º 24
0
def as_ast(dct):
    """See https://docs.python.org/2/library/ast.html"""
    if dct['ast_type'] == "Module":
        return ast.Module(dct["body"])
    elif dct['ast_type'] == "Interactive":
        return ast.Interactive(dct["body"])
    elif dct['ast_type'] == "Expression":
        return ast.Expression(dct["body"])
    elif dct['ast_type'] == "Suite":
        return ast.Suite(dct["body"])
    elif dct['ast_type'] == "FunctionDef":
        return ast.FunctionDef(dct["name"], dct["args"], dct["body"],
                               dct["decorator_list"])
    elif dct['ast_type'] == "ClassDef":
        return ast.ClassDef(dct["name"], dct["bases"], dct["body"],
                            dct["decorator_list"])
    elif dct['ast_type'] == "Return":
        return ast.Return(dct["value"])
    elif dct['ast_type'] == "Delete":
        return ast.Delete(dct["targets"])
    elif dct['ast_type'] == "Assign":
        return ast.Assign(dct["targets"], dct["value"])
    elif dct['ast_type'] == "AugAssign":
        return ast.AugAssign(dct["target"], dct["op"], dct["value"])
    elif dct['ast_type'] == "Print":
        return ast.Print(dct["dest"], dct["values"], dct["nl"])
    elif dct['ast_type'] == "For":
        return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "While":
        return ast.While(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "If":
        return ast.If(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "With":
        return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"])
    elif dct['ast_type'] == "Raise":
        return ast.Raise(dct["type"], dct["inst"], dct["tback"])
    elif dct['ast_type'] == "TryExcept":
        return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"])
    elif dct['ast_type'] == "TryFinally":
        return ast.TryFinally(dct["body"], dct["finalbody"])
    elif dct['ast_type'] == "Assert":
        return ast.Assert(dct["test"], dct["msg"])
    elif dct['ast_type'] == "Import":
        return ast.Import(dct["names"])
    elif dct['ast_type'] == "ImportFrom":
        return ast.ImportFrom(dct["module"], dct["names"], dct["level"])
    elif dct['ast_type'] == "Exec":
        return ast.Exec(dct["body"], dct["globals"], dct["locals"])
    elif dct['ast_type'] == "Global":
        return ast.Global(dct["names"])
    elif dct['ast_type'] == "Expr":
        return ast.Expr(dct["value"])
    elif dct['ast_type'] == "Pass":
        return ast.Pass()
    elif dct['ast_type'] == "Break":
        return ast.Break()
    elif dct['ast_type'] == "Continue":
        return ast.Continue()
    elif dct['ast_type'] == "BoolOp":
        return ast.BoolOp(dct["op"], dct["values"])
    elif dct['ast_type'] == "BinOp":
        return ast.BinOp(dct["left"], dct["op"], dct["right"])
    elif dct['ast_type'] == "UnaryOp":
        return ast.UnaryOp(dct["op"], dct["operand"])
    elif dct['ast_type'] == "Lambda":
        return ast.Lambda(dct["args"], dct["body"])
    elif dct['ast_type'] == "IfExp":
        return ast.IfExp(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "Dict":
        return ast.Dict(dct["keys"], dct["values"])
    elif dct['ast_type'] == "Set":
        return ast.Set(dct["elts"])
    elif dct['ast_type'] == "ListComp":
        return ast.ListComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "SetComp":
        return ast.SetComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "DictComp":
        return ast.DictComp(dct["key"], dct["value"], dct["generators"])
    elif dct['ast_type'] == "GeneratorExp":
        return ast.GeneratorExp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "Yield":
        return ast.Yield(dct["value"])
    elif dct['ast_type'] == "Compare":
        return ast.Compare(dct["left"], dct["ops"], dct["comparators"])
    elif dct['ast_type'] == "Call":
        return ast.Call(dct["func"], dct["args"], dct["keywords"],
                        dct["starargs"], dct["kwargs"])
    elif dct['ast_type'] == "Repr":
        return ast.Repr(dct["value"])
    elif dct['ast_type'] == "Num":
        return ast.Num(dct["n"])
    elif dct['ast_type'] == "Str":
        # Converting to ASCII
        return ast.Str(dct["s"].encode('ascii', 'ignore'))
    elif dct['ast_type'] == "Attribute":
        return ast.Attribute(dct["value"], dct["attr"], dct["ctx"])
    elif dct['ast_type'] == "Subscript":
        return ast.Subscript(dct["value"], dct["slice"], dct["ctx"])
    elif dct['ast_type'] == "Name":
        return ast.Name(dct["id"], dct["ctx"])
    elif dct['ast_type'] == "List":
        return ast.List(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Tuple":
        return ast.Tuple(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Load":
        return ast.Load()
    elif dct['ast_type'] == "Store":
        return ast.Store()
    elif dct['ast_type'] == "Del":
        return ast.Del()
    elif dct['ast_type'] == "AugLoad":
        return ast.AugLoad()
    elif dct['ast_type'] == "AugStore":
        return ast.AugStore()
    elif dct['ast_type'] == "Param":
        return ast.Param()
    elif dct['ast_type'] == "Ellipsis":
        return ast.Ellipsis()
    elif dct['ast_type'] == "Slice":
        return ast.Slice(dct["lower"], dct["upper"], dct["step"])
    elif dct['ast_type'] == "ExtSlice":
        return ast.ExtSlice(dct["dims"])
    elif dct['ast_type'] == "Index":
        return ast.Index(dct["value"])
    elif dct['ast_type'] == "And":
        return ast.And()
    elif dct['ast_type'] == "Or":
        return ast.Or()
    elif dct['ast_type'] == "Add":
        return ast.Add()
    elif dct['ast_type'] == "Sub":
        return ast.Sub()
    elif dct['ast_type'] == "Mult":
        return ast.Mult()
    elif dct['ast_type'] == "Div":
        return ast.Div()
    elif dct['ast_type'] == "Mod":
        return ast.Mod()
    elif dct['ast_type'] == "Pow":
        return ast.Pow()
    elif dct['ast_type'] == "LShift":
        return ast.LShift()
    elif dct['ast_type'] == "RShift":
        return ast.RShift()
    elif dct['ast_type'] == "BitOr":
        return ast.BitOr()
    elif dct['ast_type'] == "BitXor":
        return ast.BitXor()
    elif dct['ast_type'] == "BitAnd":
        return ast.BitAnd()
    elif dct['ast_type'] == "FloorDiv":
        return ast.FloorDiv()
    elif dct['ast_type'] == "Invert":
        return ast.Invert()
    elif dct['ast_type'] == "Not":
        return ast.Not()
    elif dct['ast_type'] == "UAdd":
        return ast.UAdd()
    elif dct['ast_type'] == "USub":
        return ast.USub()
    elif dct['ast_type'] == "Eq":
        return ast.Eq()
    elif dct['ast_type'] == "NotEq":
        return ast.NotEq()
    elif dct['ast_type'] == "Lt":
        return ast.Lt()
    elif dct['ast_type'] == "LtE":
        return ast.LtE()
    elif dct['ast_type'] == "Gt":
        return ast.Gt()
    elif dct['ast_type'] == "GtE":
        return ast.GtE()
    elif dct['ast_type'] == "Is":
        return ast.Is()
    elif dct['ast_type'] == "IsNot":
        return ast.IsNot()
    elif dct['ast_type'] == "In":
        return ast.In()
    elif dct['ast_type'] == "NotIn":
        return ast.NotIn()
    elif dct['ast_type'] == "comprehension":
        return ast.comprehension(dct["target"], dct["iter"], dct["ifs"])
    elif dct['ast_type'] == "ExceptHandler":
        return ast.ExceptHandler(dct["type"], dct["name"], dct["body"])
    elif dct['ast_type'] == "arguments":
        return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"],
                             dct["defaults"])
    elif dct['ast_type'] == "keyword":
        return ast.keyword(dct["arg"], dct["value"])
    elif dct['ast_type'] == "alias":
        return ast.alias(dct["name"], dct["asname"])
    else:
        return dct
Ejemplo n.º 25
0
def from_phpast(node):
    if node is None:
        return py.Pass(**pos(node))

    if isinstance(node, str):
        return py.Str(node, **pos(node))

    if isinstance(node, (int, float)):
        return py.Num(node, **pos(node))

    if isinstance(node, php.Array):
        if node.nodes:
            if node.nodes[0].key is not None:
                keys = []
                values = []
                for elem in node.nodes:
                    keys.append(from_phpast(elem.key))
                    values.append(from_phpast(elem.value))
                return py.Dict(keys, values, **pos(node))
            else:
                return py.List([from_phpast(x.value) for x in node.nodes],
                               py.Load(**pos(node)), **pos(node))
        else:
            return py.List([], py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.InlineHTML):
        args = [py.Str(node.data, **pos(node))]
        return py.Call(
            py.Name('inline_html', py.Load(**pos(node)), **pos(node)), args,
            [], None, None, **pos(node))

    if isinstance(node, php.Echo):
        return py.Call(py.Name('echo', py.Load(**pos(node)), **pos(node)),
                       list(map(from_phpast, node.nodes)), [], None, None,
                       **pos(node))

    if isinstance(node, php.Print):
        return py.Print(None, [from_phpast(node.node)], True, **pos(node))

    if isinstance(node, php.Exit):
        args = []
        if node.expr is not None:
            args.append(from_phpast(node.expr))
        return py.Raise(
            py.Call(py.Name('Exit', py.Load(**pos(node)), **pos(node)), args,
                    [], None, None, **pos(node)), None, None, **pos(node))

    if isinstance(node, php.Return):
        if node.node is None:
            return py.Return(None, **pos(node))
        else:
            return py.Return(from_phpast(node.node), **pos(node))

    if isinstance(node, php.Break):
        assert node.node is None, 'level on break not supported'
        return py.Break(**pos(node))

    if isinstance(node, php.Continue):
        assert node.node is None, 'level on continue not supported'
        return py.Continue(**pos(node))

    if isinstance(node, php.Silence):
        return from_phpast(node.expr)

    if isinstance(node, php.Block):
        return from_phpast(php.If(1, node, [], None, lineno=node.lineno))

    if isinstance(node, php.Unset):
        return py.Delete(list(map(from_phpast, node.nodes)), **pos(node))

    if isinstance(node, php.IsSet) and len(node.nodes) == 1:
        if isinstance(node.nodes[0], php.ArrayOffset):
            return py.Compare(from_phpast(node.nodes[0].expr),
                              [py.In(**pos(node))],
                              [from_phpast(node.nodes[0].node)], **pos(node))
        if isinstance(node.nodes[0], php.ObjectProperty):
            return py.Call(
                py.Name('hasattr', py.Load(**pos(node)), **pos(node)), [
                    from_phpast(node.nodes[0].node),
                    from_phpast(node.nodes[0].name)
                ], [], None, None, **pos(node))
        if isinstance(node.nodes[0], php.Variable):
            return py.Compare(py.Str(
                node.nodes[0].name[1:], **pos(node)), [py.In(**pos(node))], [
                    py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)),
                            [], [], None, None, **pos(node))
                ], **pos(node))
        return py.Compare(from_phpast(node.nodes[0]), [py.IsNot(**pos(node))],
                          [py.Name('None', py.Load(**pos(node)), **pos(node))],
                          **pos(node))

    if isinstance(node, php.Empty):
        return from_phpast(
            php.UnaryOp('!',
                        php.BinaryOp('&&',
                                     php.IsSet([node.expr],
                                               lineno=node.lineno),
                                     node.expr,
                                     lineno=node.lineno),
                        lineno=node.lineno))

    if isinstance(node, php.Assignment):
        if (isinstance(node.node, php.ArrayOffset) and node.node.expr is None):
            return py.Call(
                py.Attribute(from_phpast(node.node.node), 'append',
                             py.Load(**pos(node)), **pos(node)),
                [from_phpast(node.expr)], [], None, None, **pos(node))
        if (isinstance(node.node, php.ObjectProperty)
                and isinstance(node.node.name, php.BinaryOp)):
            return to_stmt(
                py.Call(py.Name('setattr', py.Load(**pos(node)), **pos(node)),
                        [
                            from_phpast(node.node.node),
                            from_phpast(node.node.name),
                            from_phpast(node.expr)
                        ], [], None, None, **pos(node)))
        return py.Assign([store(from_phpast(node.node))],
                         from_phpast(node.expr), **pos(node))

    if isinstance(node, php.ListAssignment):
        return py.Assign([
            py.Tuple(list(map(store, list(map(from_phpast, node.nodes)))),
                     py.Store(**pos(node)), **pos(node))
        ], from_phpast(node.expr), **pos(node))

    if isinstance(node, php.AssignOp):
        return from_phpast(
            php.Assignment(node.left,
                           php.BinaryOp(node.op[:-1],
                                        node.left,
                                        node.right,
                                        lineno=node.lineno),
                           False,
                           lineno=node.lineno))

    if isinstance(node, (php.PreIncDecOp, php.PostIncDecOp)):
        return from_phpast(
            php.Assignment(node.expr,
                           php.BinaryOp(node.op[0],
                                        node.expr,
                                        1,
                                        lineno=node.lineno),
                           False,
                           lineno=node.lineno))

    if isinstance(node, php.ArrayOffset):
        return py.Subscript(from_phpast(node.node),
                            py.Index(from_phpast(node.expr), **pos(node)),
                            py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.ObjectProperty):
        if isinstance(node.name, (php.Variable, php.BinaryOp)):
            return py.Call(
                py.Name('getattr', py.Load(**pos(node)), **pos(node)),
                [from_phpast(node.node),
                 from_phpast(node.name)], [], None, None, **pos(node))
        return py.Attribute(from_phpast(node.node), node.name,
                            py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Constant):
        name = node.name
        if name.lower() == 'true': name = 'True'
        if name.lower() == 'false': name = 'False'
        if name.lower() == 'null': name = 'None'
        return py.Name(name, py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Variable):
        name = node.name[1:]
        if name == 'this': name = 'self'
        return py.Name(name, py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Global):
        return py.Global([var.name[1:] for var in node.nodes], **pos(node))

    if isinstance(node, php.Include):
        once = py.Name('True' if node.once else 'False', py.Load(**pos(node)),
                       **pos(node))
        return py.Call(py.Name('include', py.Load(**pos(node)), **pos(node)),
                       [from_phpast(node.expr), once], [], None, None,
                       **pos(node))

    if isinstance(node, php.Require):
        once = py.Name('True' if node.once else 'False', py.Load(**pos(node)),
                       **pos(node))
        return py.Call(py.Name('require', py.Load(**pos(node)), **pos(node)),
                       [from_phpast(node.expr), once], [], None, None,
                       **pos(node))

    if isinstance(node, php.UnaryOp):
        op = unary_ops.get(node.op)
        assert op is not None, "unknown unary operator: '%s'" % node.op
        op = op(**pos(node))
        return py.UnaryOp(op, from_phpast(node.expr), **pos(node))

    if isinstance(node, php.BinaryOp):
        if node.op == '.':
            pattern, pieces = build_format(node.left, node.right)
            if pieces:
                return py.BinOp(
                    py.Str(pattern, **pos(node)), py.Mod(**pos(node)),
                    py.Tuple(list(map(from_phpast, pieces)),
                             py.Load(**pos(node)), **pos(node)), **pos(node))
            else:
                return py.Str(pattern % (), **pos(node))
        if node.op in bool_ops:
            op = bool_ops[node.op](**pos(node))
            return py.BoolOp(op,
                             [from_phpast(node.left),
                              from_phpast(node.right)], **pos(node))
        if node.op in cmp_ops:
            op = cmp_ops[node.op](**pos(node))
            return py.Compare(from_phpast(node.left), [op],
                              [from_phpast(node.right)], **pos(node))
        op = binary_ops.get(node.op)
        if node.op == 'instanceof':
            return py.Call(
                func=py.Name(id='isinstance', ctx=py.Load(**pos(node))),
                args=[from_phpast(node.left),
                      from_phpast(node.right)],
                keywords=[],
                starargs=None,
                kwargs=None)
        assert op is not None, "unknown binary operator: '%s'" % node.op
        op = op(**pos(node))
        return py.BinOp(from_phpast(node.left), op, from_phpast(node.right),
                        **pos(node))

    if isinstance(node, php.TernaryOp):
        return py.IfExp(from_phpast(node.expr), from_phpast(node.iftrue),
                        from_phpast(node.iffalse), **pos(node))

    if isinstance(node, php.Cast):
        return py.Call(
            py.Name(casts.get(node.type, node.type), py.Load(**pos(node)),
                    **pos(node)), [from_phpast(node.expr)], [], None, None,
            **pos(node))

    if isinstance(node, php.If):
        orelse = []
        if node.else_:
            for else_ in map(from_phpast, deblock(node.else_.node)):
                orelse.append(to_stmt(else_))
        for elseif in reversed(node.elseifs):
            orelse = [
                py.If(
                    from_phpast(elseif.expr),
                    list(
                        map(to_stmt,
                            list(map(from_phpast, deblock(elseif.node))))),
                    orelse, **pos(node))
            ]
        return py.If(
            from_phpast(node.expr),
            list(map(to_stmt, list(map(from_phpast, deblock(node.node))))),
            orelse, **pos(node))

    if isinstance(node, php.For):
        assert node.test is None or len(node.test) == 1, \
            'only a single test is supported in for-loops'
        return from_phpast(
            php.Block((node.start or []) + [
                php.While(node.test[0] if node.test else 1,
                          php.Block(deblock(node.node) + (node.count or []),
                                    lineno=node.lineno),
                          lineno=node.lineno)
            ],
                      lineno=node.lineno))

    if isinstance(node, php.Foreach):
        if node.keyvar is None:
            target = py.Name(node.valvar.name[1:], py.Store(**pos(node)),
                             **pos(node))
        else:
            target = py.Tuple([
                py.Name(node.keyvar.name[1:], py.Store(**pos(node))),
                py.Name(node.valvar.name[1:], py.Store(**pos(node)))
            ], py.Store(**pos(node)), **pos(node))
        return py.For(
            target, from_phpast(node.expr),
            list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [],
            **pos(node))

    if isinstance(node, php.While):
        return py.While(
            from_phpast(node.expr),
            list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [],
            **pos(node))

    if isinstance(node, php.DoWhile):
        condition = php.If(php.UnaryOp('!', node.expr, lineno=node.lineno),
                           php.Break(None, lineno=node.lineno), [],
                           None,
                           lineno=node.lineno)
        return from_phpast(
            php.While(1,
                      php.Block(deblock(node.node) + [condition],
                                lineno=node.lineno),
                      lineno=node.lineno))

    if isinstance(node, php.Try):
        return py.TryExcept(
            list(map(to_stmt, list(map(from_phpast, node.nodes)))), [
                py.ExceptHandler(
                    py.Name(catch.class_, py.Load(**pos(node)), **pos(node)),
                    store(from_phpast(catch.var)),
                    list(map(to_stmt, list(map(from_phpast, catch.nodes)))),
                    **pos(node)) for catch in node.catches
            ], [], **pos(node))

    if isinstance(node, php.Throw):
        return py.Raise(from_phpast(node.node), None, None, **pos(node))

    if isinstance(node, php.Function):
        args = []
        defaults = []
        for param in node.params:
            args.append(
                py.Name(param.name[1:], py.Param(**pos(node)), **pos(node)))
            if param.default is not None:
                defaults.append(from_phpast(param.default))
        body = list(map(to_stmt, list(map(from_phpast, node.nodes))))
        if not body: body = [py.Pass(**pos(node))]
        return py.FunctionDef(node.name,
                              py.arguments(args, None, None, defaults), body,
                              [], **pos(node))

    if isinstance(node, php.Method):
        args = []
        defaults = []
        decorator_list = []
        if 'static' in node.modifiers:
            decorator_list.append(
                py.Name('classmethod', py.Load(**pos(node)), **pos(node)))
            args.append(py.Name('cls', py.Param(**pos(node)), **pos(node)))
        else:
            args.append(py.Name('self', py.Param(**pos(node)), **pos(node)))
        for param in node.params:
            args.append(
                py.Name(param.name[1:], py.Param(**pos(node)), **pos(node)))
            if param.default is not None:
                defaults.append(from_phpast(param.default))
        body = list(map(to_stmt, list(map(from_phpast, node.nodes))))
        if not body: body = [py.Pass(**pos(node))]
        return py.FunctionDef(node.name,
                              py.arguments(args, None, None, defaults), body,
                              decorator_list, **pos(node))

    if isinstance(node, php.Class):
        name = node.name
        bases = []
        extends = node.extends or 'object'
        bases.append(py.Name(extends, py.Load(**pos(node)), **pos(node)))
        body = list(map(to_stmt, list(map(from_phpast, node.nodes))))
        for stmt in body:
            if (isinstance(stmt, py.FunctionDef)
                    and stmt.name in (name, '__construct')):
                stmt.name = '__init__'
        if not body: body = [py.Pass(**pos(node))]
        return py.ClassDef(name, bases, body, [], **pos(node))

    if isinstance(node, (php.ClassConstants, php.ClassVariables)):
        assert len(node.nodes) == 1, \
            'only one class-level assignment supported per line'
        if isinstance(node.nodes[0], php.ClassConstant):
            name = php.Constant(node.nodes[0].name, lineno=node.lineno)
        else:
            name = php.Variable(node.nodes[0].name, lineno=node.lineno)
        initial = node.nodes[0].initial
        if initial is None:
            initial = php.Constant('None', lineno=node.lineno)
        return py.Assign([store(from_phpast(name))], from_phpast(initial),
                         **pos(node))

    if isinstance(node, (php.FunctionCall, php.New)):
        if isinstance(node.name, str):
            name = py.Name(node.name, py.Load(**pos(node)), **pos(node))
        else:
            name = py.Subscript(
                py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)), [],
                        [], None, None, **pos(node)),
                py.Index(from_phpast(node.name), **pos(node)),
                py.Load(**pos(node)), **pos(node))
        args, kwargs = build_args(node.params)
        return py.Call(name, args, kwargs, None, None, **pos(node))

    if isinstance(node, php.MethodCall):
        args, kwargs = build_args(node.params)
        return py.Call(
            py.Attribute(from_phpast(node.node), node.name,
                         py.Load(**pos(node)), **pos(node)), args, kwargs,
            None, None, **pos(node))

    if isinstance(node, php.StaticMethodCall):
        class_ = node.class_
        if class_ == 'self': class_ = 'cls'
        args, kwargs = build_args(node.params)
        return py.Call(
            py.Attribute(py.Name(class_, py.Load(**pos(node)),
                                 **pos(node)), node.name, py.Load(**pos(node)),
                         **pos(node)), args, kwargs, None, None, **pos(node))

    if isinstance(node, php.StaticProperty):
        class_ = node.node
        name = node.name
        if isinstance(name, php.Variable):
            name = name.name[1:]
        return py.Attribute(py.Name(class_, py.Load(**pos(node)), **pos(node)),
                            name, py.Load(**pos(node)), **pos(node))

    return py.Call(py.Name('XXX', py.Load(**pos(node)),
                           **pos(node)), [py.Str(str(node), **pos(node))], [],
                   None, None, **pos(node))
Ejemplo n.º 26
0
COMMENT = Comment()


class Char(object):
    def __init__(self, str, lineno=0):
        self.value = str
        self.lineno = lineno


op_ast_map = {
    '+': ast.Add(),
    '-': ast.Sub(),
    '*': ast.Mult(),
    '/': ast.Div(),
    '%': ast.Mod(),
    '**': ast.Pow(),
    '<<': ast.LShift(),
    '>>': ast.RShift(),
    '|': ast.BitOr(),
    '^^': ast.BitXor(),
    '&&': ast.BitAnd(),
    '//': ast.FloorDiv(),
    '==': ast.Eq(),
    '!=': ast.NotEq(),
    '<': ast.Lt(),
    '<=': ast.LtE(),
    '>': ast.Gt(),
    '>=': ast.GtE(),
    'is': ast.Is(),
    'is_not': ast.IsNot(),
Ejemplo n.º 27
0
 def __mod__(self, other: Union[T, Expr[T]]) -> BinOp[T]:
     return BinOp(self, ast.Mod(), other)
Ejemplo n.º 28
0
class LtnsCompiler:
    def _temp_func_name(self):
        if not hasattr(self, '_temp'):
            self._temp = 0
        self._temp += 1
        return f'_temp_func_{self._temp}'

    def _temp_var_name(self):
        if not hasattr(self, '_temp'):
            self._temp = 0
        self._temp += 1
        return f'_temp_var_{self._temp}'

    def _compile_branch(self, branch):
        result = Result()

        for x in branch[:-1]:
            res = self.compile(x)
            result.stmts += res.stmts
            result.stmts += [res.expr_statement]

        res = self.compile(branch[-1])
        result.stmts += res.stmts
        result.expr = res.expr

        return result

    def _compile_args(self, args, kwargs):
        for i, arg in enumerate(args):
            if arg == '&':
                vararg = ast.arg(str(args[i + 1], None), None)
                posarg = args[:i]
        else:
            vararg = None
            posarg = args

        return ast.arguments(
            args=[ast.arg(str(x), None) for x in posarg],
            vararg=vararg,
            kwonlyargs=[ast.arg(str(x), None) for x in kwargs],
            kwarg=None,
            defaults=[],
            kw_defaults=list(kwargs.values()),
        )

    def compile(self, node):
        return _model_compiler[type(node)](self, node)

    @model(LtnsElement)
    def compile_element(self, element):
        if element.name in _special_form_compiler:
            return _special_form_compiler[element.name](self, *element.childs,
                                                        **element.attributes)

        func = ast.parse(element.name,
                         mode='eval').body  # TODO: handle exception of parsing

        result = Result()

        args = []
        keywords = []

        for child in element.childs:
            res = self.compile(child)
            args.append(res.expr)
            result.stmts += res.stmts

        for key, value in element.attributes.items():
            res = self.compile(value)
            keywords.append(ast.keyword(arg=str(key), value=res.expr))
            result.stmts += res.stmts

        expr = ast.Call(func=func, args=args, keywords=keywords)
        result.expr = expr

        return result

    @model(LtnsSymbol)
    def compile_symbol(self, symbol):
        expr = ast.Name(id=str(symbol), ctx=ast.Load())

        return Result(expr=expr)

    @model(LtnsString)
    def compile_string(self, string):
        return Result(expr=ast.Str(str(string)))

    @model(LtnsKeyword)
    def compile_keyword(self, keyword):
        return Result(expr=ast.Call(
            func=ast.Name(id='LtnsKeyword', ctx=ast.Load()),
            args=[ast.Str(str(keyword))],
        ))

    @model(LtnsInteger)
    def compile_integer(self, integer):
        return Result(expr=ast.Num(int(integer)))

    @model(LtnsFloat)
    def compile_float_number(self, float_number):
        return Result(expr=ast.Num(float(float_number)))

    @model(LtnsComplex)
    def compile_complex_number(self, complex_number):
        return Result(expr=ast.Num(complex(complex_number)))

    @model(LtnsList)
    def compile_list(self, ltns_list):
        result = Result()

        elts = []
        for e in ltns_list:
            res = self.compile(e)
            elts.append(res.expr)
            result.stmts += res.stmts

        expr = ast.List(elts=elts, ctx=ast.Load())
        result.expr = expr

        return result

    @special('do')
    def compile_do(self, *body):
        return self._compile_branch(body)

    name_op = {
        'add*': ast.Add(),
        'sub*': ast.Sub(),
        'mul*': ast.Mult(),
        'div*': ast.Div(),
        'mod': ast.Mod(),
        'pow': ast.Pow(),
        'lshift': ast.LShift(),
        'rshift': ast.RShift(),
        'bitor': ast.BitOr(),
        'bitxor': ast.BitXor(),
        'bitand': ast.BitAnd(),
    }

    def compile_bin_op(self, a, b, name):
        result = Result()

        left = self.compile(a)
        result.stmts += left.stmts
        left = left.expr

        right = self.compile(b)
        result.stmts += right.stmts
        right = right.expr

        expr = ast.BinOp(op=self.name_op[name], left=left, right=right)
        result.expr = expr

        return result

    for name in name_op:
        _special_form_compiler[name] = partial(compile_bin_op, name=name)

    @special('if')
    def compile_if(self, test, then, orelse=None):
        result = Result()

        pred = self.compile(test)
        result.stmts += pred.stmts

        then_body = self.compile(then)

        else_body = None
        if orelse is not None:
            else_body = self.compile(orelse)

        if then_body.stmts or else_body.stmts:
            temp_func_name = self._temp_func_name()
            temp_var_name = self._temp_var_name()

            body = then_body.stmts
            body.append(
                ast.Assign(
                    targets=[ast.Name(id=temp_var_name, ctx=ast.Store())],
                    value=then_body.expr,
                ))

            orelse = else_body.stmts
            orelse.append(
                ast.Assign(
                    targets=[ast.Name(id=temp_var_name, ctx=ast.Store())],
                    value=else_body.expr,
                ))

            result.stmts.append(
                ast.FunctionDef(
                    name=temp_func_name,
                    args=ast.arguments(
                        args=[],
                        vararg=None,
                        kwonlyargs=[],
                        kw_defaults=[],
                        kwarg=None,
                        defaults=[],
                    ),
                    body=[
                        ast.If(test=pred.expr, body=body, orelse=orelse),
                        ast.Return(
                            value=ast.Name(id=temp_var_name, ctx=ast.Load())),
                    ],
                    decorator_list=[],
                    returns=None,
                ))

            result.expr = ast.Call(
                func=ast.Name(id=temp_func_name, ctx=ast.Load()),
                args=[],
                keywords=[],
            )

            return result
        else:
            result.expr = ast.IfExp(
                test=pred.expr,
                body=then_body.expr,
                orelse=else_body.expr,
            )

            return result

    @special('fn*')
    def compile_fn(self, args, *body, **kwargs):
        result = Result()

        body = self._compile_branch(body)
        args = self._compile_args(args, kwargs)

        if body.stmts:
            fdef = ast.FunctionDef()
            fdef.name = self._temp_func_name()
            fdef.args = args
            fdef.body = body.stmts + [ast.Return(body.expr)]
            fdef.decorator_list = []
            fdef.returns = None

            result.stmts += [fdef]
            result.expr = ast.Name(id=fdef.name, ctx=ast.Load())
        else:
            result.expr = ast.Lambda(args=args, body=body.expr)

        return result

    @special('def')
    def compile_def(self, *name_value, **def_dict):
        if len(name_value) % 2 != 0:
            raise ValueError("length of argument list should be even")

        result = Result()

        for name, value in def_dict.items():
            name = LtnsSymbol(name)
            name_value = name_value + (name, value)

        for i, name in enumerate(name_value[::2]):
            name = ast.Name(id=str(name), ctx=ast.Store())
            value = self.compile(name_value[i * 2 + 1])

            result.stmts += [ast.Assign(
                targets=[name],
                value=value.expr,
            )]

        result.expr = ast.Name(id='None', ctx=ast.Load())

        return result
Ejemplo n.º 29
0
def compile_subtract(p):
    if len(p) == 2:
        return ast.UnaryOp(ast.USub(), build_ast(p[1]))
    elif len(p) == 3:
        return ast.BinOp(build_ast(p[1]), ast.Sub(), build_ast(p[2]))
    else:
        return ast.BinOp(compile_subtract(p[:-1]), ast.Sub(), build_ast(p[-1]))

CompileFuncs = {
    Symbol.new("+"): compile_add,
    Symbol.new("-"): compile_subtract,
    Symbol.new("*"): compile_multiply,
    Symbol.new("/"): compile_divide,
    Symbol.new("//"): compile_floordivide,
    Symbol.new("%"): lambda p: ast.BinOp(build_ast(p[1]), ast.Mod(), build_ast(p[2])),
    Symbol.new("&"): lambda p: ast.BinOp(build_ast(p[1]), ast.BitAnd(), build_ast(p[2])),
    Symbol.new("**"): lambda p: ast.BinOp(build_ast(p[1]), ast.Pow(), build_ast(p[2])),
    Symbol.new(">>"): lambda p: ast.BinOp(build_ast(p[1]), ast.RShift(), build_ast(p[2])),
    Symbol.new("<<"): lambda p: ast.BinOp(build_ast(p[1]), ast.LShift(), build_ast(p[2])),
    Symbol.new("^"): lambda p: ast.BinOp(build_ast(p[1]), ast.BitXor(), build_ast(p[2])),
    Symbol.new("<"): lambda p: ast.Compare(build_ast(p[1]), [ast.Lt() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new(">"): lambda p: ast.Compare(build_ast(p[1]), [ast.Gt() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new("<="): lambda p: ast.Compare(build_ast(p[1]), [ast.LtE() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new(">="): lambda p: ast.Compare(build_ast(p[1]), [ast.GtE() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new("=="): compile_equals,
    Symbol.new("!="): lambda p: ast.Compare(build_ast(p[1]), [ast.NotEq() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new("is"): lambda p: ast.Compare(build_ast(p[1]), [ast.Is() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new("is-not"): lambda p: ast.Compare(build_ast(p[1]), [ast.IsNot() for x in p[1::2]], [build_ast(x) for x in p[2::2]]),
    Symbol.new("define"): compile_define,
    Symbol.new("dict-set"): lambda p: ast.Assign([ast.Subscript(build_ast(p[1]), ast.Index(build_ast(p[2])), ast.Store())], build_ast(p[3])),
Ejemplo n.º 30
0
	def __build_function(self, dom_name, full_name, func_params):

		assert 'name' in func_params
		func_name = func_params['name']

		docstr = self.__build_desc_string(dom_name, func_name, func_params)

		args = [ast.arg('self', None)]
		message_params = []
		func_body = []

		if docstr:
			func_body.append(ast.Expr(ast.Str("\n"+docstr+"\n\t\t")))

		for param in func_params.get("parameters", []):

			argname = param['name']


			param_optional = param.get("optional", False)

			if param_optional is False:
				message_params.append(ast.keyword(argname, ast.Name(id=argname, ctx=ast.Load())))
				args.append(ast.arg(argname, None))
				if self.do_debug_prints:
					func_body.append(self.__build_debug_print(argname, argname))



			param_type = param.get("type", None)
			if param_type in CHECKS:
				if param_optional:
					check = self.__build_conditional_arg_check(argname, CHECKS[param_type])
				else:
					check = self.__build_unconditional_arg_check(argname, CHECKS[param_type])

				if check:
					func_body.append(check)




		optional_params = [param.get("name") for param in func_params.get("parameters", []) if param.get("optional", False)]
		func_kwargs = None
		if len(optional_params):


			value = ast.List(elts=[ast.Str(s=param, ctx=ast.Store()) for param in optional_params], ctx=ast.Load())
			create_list = ast.Assign(targets=[ast.Name(id='expected', ctx=ast.Store())], value=value)

			func_body.append(create_list)

			passed_arg_list = ast.Assign(targets=[ast.Name(id='passed_keys', ctx=ast.Store())],
				value=ast.Call(func=ast.Name(id='list', ctx=ast.Load()),
				args=[ast.Call(func=ast.Attribute(value=ast.Name(id='kwargs', ctx=ast.Load()), attr='keys', ctx=ast.Load()), args=[], keywords=[])],
				keywords=[]))

			func_body.append(passed_arg_list)

			comprehension = ast.comprehension(target=ast.Name(id='key', ctx=ast.Store()), iter=ast.Name(id='passed_keys', ctx=ast.Load()), ifs=[], is_async=False)
			comparator = ast.Name(id='expected', ctx=ast.Load())

			listcomp = ast.ListComp(elt=ast.Compare(left=ast.Name(id='key', ctx=ast.Load()), ops=[ast.In()], comparators=[comparator]), generators=[comprehension])

			check_message = ast.BinOp(
					left         = ast.Str(s="Allowed kwargs are {}. Passed kwargs: %s".format(optional_params)),
					op           = ast.Mod(),
					right        = ast.Name(id='passed_keys', ctx=ast.Load()),
					lineno       = self.__get_line())

			kwarg_check = ast.Assert(test=ast.Call(func=ast.Name(id='all', ctx=ast.Load()), args=[listcomp], keywords=[]), msg=check_message)
			func_body.append(kwarg_check)

			func_kwargs = ast.Name(id='kwargs', ctx=ast.Load())


		fname = "{}.{}".format(dom_name, func_name)
		fname = ast.Str(s=fname, ctx=ast.Load())


		if (sys.version_info[0], sys.version_info[1]) == (3, 5) or \
			(sys.version_info[0], sys.version_info[1]) == (3, 6):

			# More irritating minor semantic differences in the AST between 3.4 and 3.5
			if func_kwargs:
				message_params.append(ast.keyword(arg=None, value=ast.Name(id='kwargs', ctx=ast.Load())))

			communicate_call = ast.Call(
					func=ast.Attribute(value=ast.Name(id='self', ctx=ast.Load()), ctx=ast.Load(), attr='synchronous_command'),
					args=[fname],
					keywords=message_params)

		elif (sys.version_info[0], sys.version_info[1]) == (3,4):

			communicate_call = ast.Call(
					func=ast.Attribute(value=ast.Name(id='self', ctx=ast.Load()), ctx=ast.Load(), attr='synchronous_command'),
					args=[fname],
					kwargs=func_kwargs,
					keywords=message_params)
		else:
			print("Version:", sys.version_info)
			raise RuntimeError("This script only functions on python 3.4, 3.5 or 3.6. Active python version {}.{}".format(*sys.version_info))


		do_communicate = ast.Assign(targets=[ast.Name(id='subdom_funcs', ctx=ast.Store())], value=communicate_call)
		func_ret = ast.Return(value=ast.Name(id='subdom_funcs', ctx=ast.Load()))


		if len(optional_params) and self.do_debug_prints:
			func_body.append(self.__build_debug_print('kwargs', 'kwargs'))

		func_body.append(do_communicate)
		func_body.append(func_ret)

		if len(optional_params):
			kwarg = ast.arg(arg='kwargs', annotation=None)
		else:
			kwarg = None


		sig = ast.arguments(
					args=args,
					vararg=None,
					varargannotation=None,
					kwonlyargs=[],
					kwarg=kwarg,
					kwargannotation=None,
					defaults=[],
					kw_defaults=[])

		func = ast.FunctionDef(
			name = "{}_{}".format(full_name, func_name),
			args = sig,
			body = func_body,
			decorator_list = [],
			lineno     = self.__get_line(),
			col_offset = 0,
			)

		return func