def get_iterable(self, literals):
        types = [(1.0, "range")]  # iterables that dont require size
        if self.stats.prog_size > 0:
            types = types + [(1.0, "list_comp_gen"), (1.0, "list_comp_list"),
                             (1.0, "yield_func")]

        branch = eval_branches(self.rng, types)

        if branch == "range":
            return ["range(%d)" % (self.rng.randint(1, 50))]

        if branch == "list_comp_gen":
            self.stats.prog_size -= 1

            gen = ListComprehensionGenerator(self.module, self.stats,
                                             self.opts, self.rng)
            return [gen.get_generator(literals)]

        if branch == "list_comp_list":
            self.stats.prog_size -= 1

            gen = ListComprehensionGenerator(self.module, self.stats,
                                             self.opts, self.rng)
            return [gen.get_list(literals)]

        if branch == "yield_func":
            self.stats.prog_size -= 1
            gen = YieldFunctionGenerator(self.module, self.stats, self.opts,
                                         self.rng)
            return [gen.generate(2, literals)]
    def generate(self, opts, args_num, globals=[]):
        """Insert a new arithmetic function using only integers."""
        args = self.generate_arguments(args_num)

        f = self.create_function(args)

        literals = set(args) | set(globals)

        children = min(self.rng.randint(0, opts['max_children']),
                       self.stats.prog_size)
        if children > 0:
            self.stats.prog_size -= children
            for i in range(children):
                self.generate_child(opts, f, literals)

        numbers = [n.set_rng(self.rng) for n in opts['numbers']]
        branch_type = eval_branches(self.rng, opts['type'])
        if branch_type == 'thin':
            gen = ArithGen(2, self.rng)
            for i in range(self.rng.randint(10, 25)):
                self.generate_statement(opts, f, gen, literals, numbers)

        if branch_type == 'fat':
            gen = ArithGen(20, self.rng)
            for i in range(self.rng.randint(0, 5)):
                self.generate_statement(opts, f, gen, literals, numbers)

        exp = ArithGen(10, self.rng).generate(list(literals) + numbers)
        f.content.append(Assignment('result', '=', [exp]))
        f.content.append('return result')

        return f
    def get_expression(self, literals):
        literals = list(literals) + [
            n.set_rng(self.rng) for n in [IntegerGen(-10, 10)]
        ]
        branch = eval_branches(self.rng, [(1.0, "thin"), (1.0, "fat")])

        iterable = IterableGenerator(self.module, self.stats, self.opts,
                                     self.rng).get_iterable(literals)

        literals.append('i')
        if branch == "fat":
            exp = ArithGen(10, self.rng).generate(literals)
        if branch == "thin":
            exp = ArithGen(1, self.rng).generate(literals)
        return ["%s for i in " % (exp, ), iterable]
    def generate(self):
        """Instantiates a new module and fills it randomly."""
        self.module = Module(main=True)
        self.func_number = 1
        self.arg_number = 1
        lopts = self.opts["module"]
        self.prog_size = lopts["prog_size"]
        self.module_size = lopts["module_size"] - self.prog_size

        while self.module_size > 0 or self.prog_size > 0:
            main = []
            loop = ForLoop('i', ['range(1)'], main)

            if "children" in lopts:
                branch = eval_branches(self.rng, lopts["children"])
                if branch == "arith_integer":
                    #main.append(Assignment('x', '=', ['5']))
                    f = self.arith_integer(self.opts[branch], 2)
                    x = random.randint(1, 10)
                    y = random.randint(1, 10)
                    main.append(CallStatement(f, [str(x), str(y)]))
                    #main.append("print(x, end='')")

                    self.module.content.insert(0, f)
                if branch == "arith_float":
                    main.append(Assignment('x', '=', ['5.0']))
                    main.append("print(x, end='')")
            #
            # self.module.main_body.append("print('prog_size: %d')" %
            #                             (lopts["prog_size"] - self.prog_size,))
            # self.module.main_body.append(
            #     "print('func_number: %d')" %
            #     (self.func_number,))
            # self.module.main_body.append(
            #     "print('arg_number: %d')" %
            #     (self.arg_number,))
            self.module.main_body.append(loop)

            created_size = lopts["prog_size"] - self.prog_size
            refill = min(created_size, self.module_size)
            self.module_size -= refill
            self.prog_size += refill

        self.module.content.insert(0, 'from __future__ import print_function')
        return self.module
예제 #5
0
    def generate(self, opts, args_num, globals):
        args = self.generate_arguments(args_num)
        func = self.create_function(args)

        branch = eval_branches(self.rng, opts["type"])

        if branch == "standard":
            rec = self.generate_standard_tail_call(opts)
        elif branch == "closure":
            func.content.append(Assignment("closure", "=", ["[0]"]))
            rec = self.generate_closure_tail_call(opts)
        else:
            rec = self.generate_fcall_tail_call(opts)

        func.content.append(rec)

        func.content.extend(
            [Assignment("result", "=", [CallStatement(rec, ["10", "0"])]),
             "return result"])

        self.module.content.append(func)

        return func
    def generate_child(self, opts, f, literals):
        branch = eval_branches(self.rng, opts['children'])
        if branch == 'arith_integer':
            gen = ArithIntegerGenerator(self.module, self.stats, self.opts,
                                        self.rng)
            c = gen.generate(opts, 2)
            self.module.content.insert(0, c)

            args = self.rng.sample(list(literals), 2)
            result = self.next_variable()

            call = Assignment(result, '=', [CallStatement(c, args)])
            f.content.append(call)
            literals.add(result)

        if branch == ('arith_integer', 'local'):
            gen = ArithIntegerGenerator(self.module, self.stats, self.opts,
                                        self.rng)
            c = gen.generate(opts, 2, list(literals))

            f.content.append(c)

            args = self.rng.sample(list(literals), 2)
            result = self.next_variable()

            call = Assignment(result, '=', [CallStatement(c, args)])
            f.content.append(call)
            literals.add(result)

        if branch == 'loop_integer':
            gen = LoopIntegerGenerator(self.module, self.stats, self.opts,
                                       self.rng)

            c = gen.generate(self.opts['loop_integer'], 2, [])
            self.module.content.insert(0, c)

            args = self.rng.sample(list(literals), 2)
            result = self.next_variable()

            call = Assignment(result, '=', [CallStatement(c, args)])
            f.content.append(call)
            literals.add(result)

        if branch == 'change_global':
            gen = ChangeGlobalGenerator(self.module, self.stats, self.opts,
                                        self.rng)

            c = gen.generate(self.opts['change_global'], 0, [])
            self.module.content.insert(0, c)

            result = self.next_variable()

            call = Assignment(result, '=', [CallStatement(c, [])])
            f.content.append(call)
            literals.add(result)

        if branch == 'integer_closure':
            gen = IntegerClosureGenerator(self.module, self.stats, self.opts,
                                          self.rng)
            func = gen.generate(self.opts['integer_closure'], 2, [])

            args = self.rng.sample(list(literals), 2)
            result = self.next_variable()

            call = Assignment(result, '=', [CallStatement(func, args)])
            f.content.append(call)
            literals.add(result)

        if branch == 'tail_recursion':
            gen = TailRecursionGenerator(self.module, self.stats, self.opts,
                                         self.rng)
            func = gen.generate(self.opts['tail_recursion'], 2, [])

            args = self.rng.sample(list(literals), 2)
            result = self.next_variable()

            call = Assignment(result, '=', [CallStatement(func, args)])
            f.content.append(call)
            literals.add(result)

        if branch == 'classes':
            from . import classes
            gen = classes.ClassGenerator(self.module, self.stats, self.opts,
                                         self.rng)
            result = gen.generate_inline(literals)

            f.content.extend(result)