Fixed generation of declarations late in blocks

Took 37 minutes
This commit is contained in:
ayrton 2023-11-23 08:36:02 -07:00
parent be30f1d264
commit 9ceb0b18be
2 changed files with 37 additions and 10 deletions

View file

@ -43,7 +43,8 @@ class AstGenerator:
names = get_english_words_set(['web2'], alpha=True) names = get_english_words_set(['web2'], alpha=True)
possible_names = filter(lambda x: self.settings['properties']['id-length']['max'] <= len(x) <= possible_names = filter(lambda x: self.settings['properties']['id-length']['max'] <= len(x) <=
self.settings['properties']['id-length']['max'] and not keyword.iskeyword(x), names) self.settings['properties']['id-length']['max'] and not keyword.iskeyword(x),
names)
var_name_list = list(possible_names) var_name_list = list(possible_names)
var_name_len = len(var_name_list) var_name_len = len(var_name_list)
@ -147,15 +148,15 @@ class AstGenerator:
self.ast = element self.ast = element
# optional constants here too # TODO generate constants and forward declarations
self.generate_main()
while i < self.settings['generation-options']['max-number-of-routines']: while i < self.settings['generation-options']['max-number-of-routines']:
if random.random() < self.settings['block-termination-probability']: if random.random() < self.settings['block-termination-probability']:
break break
self.generate_routine() self.generate_routine()
i += 1 i += 1
self.generate_main()
def generate_main(self): def generate_main(self):
parent = self.current_ast_element parent = self.current_ast_element
self.push_scope() self.push_scope()
@ -167,7 +168,7 @@ class AstGenerator:
element = build_xml_element(main_args, name=GAZ_PROCEDURE_TAG) element = build_xml_element(main_args, name=GAZ_PROCEDURE_TAG)
self.current_ast_element.append(element) self.current_ast_element.append(element)
self.current_ast_element = element self.current_ast_element = element
self.generate_block(return_stmt=True, return_value="0", return_type=GAZ_INT_KEY) self.generate_block(return_stmt=True, return_value="0", return_type=GAZ_INT_KEY, block_type=GAZ_PROCEDURE_TAG)
self.pop_scope() self.pop_scope()
self.current_ast_element = parent self.current_ast_element = parent
@ -183,16 +184,21 @@ class AstGenerator:
self.current_ast_element.append(element) self.current_ast_element.append(element)
self.current_ast_element = element self.current_ast_element = element
if block_type in [GAZ_PROCEDURE_TAG, GAZ_FUNCTION_TAG]:
self.generate_statements()
else:
self.generate_statements(include='declaration')
self.generate_statements(exclude='declaration')
# Generate the loop condition increment if we are in a loop # Generate the loop condition increment if we are in a loop
if block_type == GAZ_LOOP_TAG: if block_type == GAZ_LOOP_TAG:
self.generate_loop_condition_check(loop_var) self.generate_loop_condition_check(loop_var)
self.generate_loop_condition_increment(loop_var) self.generate_loop_condition_increment(loop_var)
self.generate_statements()
if return_stmt: if return_stmt:
self.generate_return(return_type=return_type, return_value=return_value) self.generate_return(return_type=return_type, return_value=return_value)
if self.settings['generation-options']['generate-dead-code']: if self.settings['generation-options']['generate-dead-code']:
self.generate_statements() self.generate_statements(exclude='declaration')
self.pop_scope() self.pop_scope()
self.current_ast_element = parent self.current_ast_element = parent
@ -227,7 +233,8 @@ class AstGenerator:
rhs = build_xml_element([], name=GAZ_RHS_TAG) rhs = build_xml_element([], name=GAZ_RHS_TAG)
operation.append(rhs) operation.append(rhs)
rhs.append(self.make_literal(GAZ_INT_KEY, "'" + str(self.settings['generation-options']['max-loop-iterations']) + "'")) rhs.append(
self.make_literal(GAZ_INT_KEY, "'" + str(self.settings['generation-options']['max-loop-iterations']) + "'"))
true_block = build_xml_element([], name=GAZ_BLOCK_TAG) true_block = build_xml_element([], name=GAZ_BLOCK_TAG)
if_stmt.append(true_block) if_stmt.append(true_block)
@ -329,7 +336,10 @@ class AstGenerator:
self.current_ast_element.append(arg.xml) self.current_ast_element.append(arg.xml)
self.current_scope.append(arg.name, arg) self.current_scope.append(arg.name, arg)
def generate_statements(self): def generate_statements(self, include=None, exclude=None):
opts = ['declaration', 'routine_call', 'conditional', 'loop', 'assignment', 'out_stream', 'in_stream']
# Number line # Number line
number_line = 180 # TODO fix the numberline stuff to reflect the settings number_line = 180 # TODO fix the numberline stuff to reflect the settings
cutoffs = [10, 30, 50, 80, 100, 140, 180] cutoffs = [10, 30, 50, 80, 100, 140, 180]
@ -343,6 +353,21 @@ class AstGenerator:
6: self.generate_in_stream, 6: self.generate_in_stream,
} }
if include is not None and exclude is not None:
raise ValueError("Cannot specify both include and exclude")
elif include is not None and include in opts:
for i in range(len(opts)):
if opts[i] in include:
continue
else:
options.pop(opts.index(opts[i]))
elif exclude is not None and exclude in opts:
options.pop(opts.index(exclude))
elif include is None and exclude is None:
pass
else:
raise ValueError("Invalid include/exclude options " + str(include) + " " + str(exclude))
while True: while True:
if random.random() < self.settings['block-termination-probability']: if random.random() < self.settings['block-termination-probability']:
break break
@ -353,6 +378,8 @@ class AstGenerator:
if cutoffs[i] < a < cutoffs[i + 1]: if cutoffs[i] < a < cutoffs[i + 1]:
try: try:
options[i]() options[i]()
except KeyError:
continue
except ValueError: except ValueError:
break break
break break

View file

@ -55,7 +55,7 @@ class Fuzzer():
with redirect_stdout(y): # Workaround for fuzzer.py:49 with redirect_stdout(y): # Workaround for fuzzer.py:49
try: try:
exec(f.read(), globals(), locals()) exec(f.read(), globals(), locals())
except (OverflowError, ZeroDivisionError): except (OverflowError, ZeroDivisionError, ValueError):
os.system("rm -f fuzzer/ground_truth/{}_{}.py".format(self.file_name, i)) os.system("rm -f fuzzer/ground_truth/{}_{}.py".format(self.file_name, i))
continue continue
with open("fuzzer/input/{}_{}.in".format(self.file_name, i), 'w') as f: with open("fuzzer/input/{}_{}.in".format(self.file_name, i), 'w') as f: