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
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)