Fixed error that when assignments fail they still leave their tag

Took 39 minutes
This commit is contained in:
ayrton 2023-11-19 16:52:14 -07:00
parent 5e5d6aeba9
commit 4ee1770092
4 changed files with 59 additions and 12 deletions

View file

@ -186,7 +186,10 @@ class AstGenerator:
i = 0 i = 0
for i in range(len(cutoffs) - 1): for i in range(len(cutoffs) - 1):
if cutoffs[i] < a < cutoffs[i + 1]: if cutoffs[i] < a < cutoffs[i + 1]:
options[i]() try:
options[i]()
except ValueError:
break
break break
def generate_int_real_expr(self): def generate_int_real_expr(self):
@ -229,7 +232,7 @@ class AstGenerator:
7: "or", 7: "or",
8: "xor", 8: "xor",
9: "not", 9: "not",
} # FIXME sometimes this will return a "" op, need to figure out why }
unary = ["not"] unary = ["not"]
@ -268,7 +271,7 @@ class AstGenerator:
self.current_nesting_depth -= 1 self.current_nesting_depth -= 1
self.current_ast_element = parent self.current_ast_element = parent
def generate_declaration(self): def generate_declaration(self, mut=None):
parent = self.current_ast_element parent = self.current_ast_element
decl_type = self.get_type(GAZ_VAR_TAG) decl_type = self.get_type(GAZ_VAR_TAG)
decl_args = [ decl_args = [
@ -278,7 +281,7 @@ class AstGenerator:
self.current_ast_element.append(element) self.current_ast_element.append(element)
self.current_ast_element = element self.current_ast_element = element
variable = self.generate_variable(decl_type) variable = self.generate_variable(decl_type, mut=mut)
self.current_ast_element.append(variable.xml) self.current_ast_element.append(variable.xml)
self.current_scope.append(variable.name, variable) self.current_scope.append(variable.name, variable)
@ -374,6 +377,10 @@ class AstGenerator:
def generate_assignment(self): def generate_assignment(self):
possible_vars = self.current_scope.get_all_defined_mutable_vars()
if len(possible_vars) == 0:
raise ValueError("No possible variables to assign to!")
# same structure as a declaration # same structure as a declaration
parent = self.current_ast_element parent = self.current_ast_element
@ -381,12 +388,7 @@ class AstGenerator:
self.current_ast_element.append(element) self.current_ast_element.append(element)
self.current_ast_element = element self.current_ast_element = element
possible_vars = self.current_scope.get_all_defined_mutable_vars()
if len(possible_vars) == 0:
self.generate_global()
possible_vars = self.current_scope.get_all_defined_mutable_vars()
assert len(possible_vars) > 0
variable = random.choice(possible_vars) variable = random.choice(possible_vars)
self.current_ast_element.append(variable.xml) self.current_ast_element.append(variable.xml)
@ -413,8 +415,12 @@ class AstGenerator:
self.current_ast_element = parent self.current_ast_element = parent
def generate_variable(self, var_type: str): def generate_variable(self, var_type: str, mut=None):
return Variable(self.get_name(GAZ_VAR_TAG), var_type, self.get_qualifier()) if mut is None:
return Variable(self.get_name(GAZ_VAR_TAG), var_type, self.get_qualifier())
else:
return Variable(self.get_name(GAZ_VAR_TAG), var_type, mut)
def generate_literal(self, var_type: str): def generate_literal(self, var_type: str):
args = [ args = [

View file

@ -232,10 +232,49 @@ class TestGeneration(unittest.TestCase):
# self.write_ast() # self.write_ast()
if self.ast_gen.ast.find("operator") is None: if self.ast_gen.ast.find("operator") is None:
l -= 1
continue continue
operator = self.ast_gen.ast.find("operator") operator = self.ast_gen.ast.find("operator")
self.assertFalse(self.is_no_op(operator)) self.assertFalse(self.is_no_op(operator))
def test_create_global(self):
self.ast_gen.ast = ET.Element("block")
self.ast_gen.current_ast_element = self.ast_gen.ast
self.ast_gen.generate_main()
global_block = self.ast_gen.current_ast_element
global_scope = self.ast_gen.current_scope
self.assertIsNotNone(self.ast_gen.ast.find("procedure"))
self.ast_gen.current_ast_element = self.ast_gen.ast.find("procedure")
self.ast_gen.generate_global()
self.assertGreater(len(global_scope.symbols), 0)
self.assertIsNotNone(global_block.find("declaration"))
def test_generate_assignment_no_declaration(self):
for l in range(1000):
self.ast_gen.ast = ET.Element("block")
self.ast_gen.current_ast_element = self.ast_gen.ast
self.ast_gen.generate_declaration(mut='var')
self.ast_gen.generate_assignment()
self.assertIsNotNone(self.ast_gen.ast.find("assignment"))
decl = self.ast_gen.ast.find("assignment")
self.assertIsNone(decl.find("declaration"))
def test_failing_assignment(self):
self.ast_gen.ast = ET.Element("block")
self.ast_gen.current_ast_element = self.ast_gen.ast
self.ast_gen.generate_main()
with self.assertRaises(ValueError):
self.ast_gen.generate_assignment()
self.assertIsNone(self.ast_gen.ast.find("assignment"))
def is_no_op(self, operator): def is_no_op(self, operator):
""" """

View file

@ -126,6 +126,8 @@ class GeneralUnparser:
self.source += self.endline self.source += self.endline
def unparse_variable(self, node, is_declaration: bool = False): def unparse_variable(self, node, is_declaration: bool = False):
if node is None:
raise ValueError("Node is None")
mut = node.get(GAZ_QUALIFIER_KEY) mut = node.get(GAZ_QUALIFIER_KEY)
type = node.get(GAZ_TY_KEY) type = node.get(GAZ_TY_KEY)
name = node.get(GAZ_NAME_KEY) name = node.get(GAZ_NAME_KEY)

View file

@ -32,7 +32,7 @@ class Fuzzer():
self.fuzzer.fuzz() self.fuzzer.fuzz()
dom = xml.dom.minidom.parseString(ET.tostring(self.fuzzer.ast).decode('utf-8')) dom = xml.dom.minidom.parseString(ET.tostring(self.fuzzer.ast).decode('utf-8'))
pretty: str = dom.toprettyxml() pretty: str = dom.toprettyxml()
with open("fuzzer/source/{}_{}.in".format(self.file_name, i), 'w') as f: with open("fuzzer/input/{}_{}.in".format(self.file_name, i), 'w') as f:
f.write(self.fuzzer.source) f.write(self.fuzzer.source)
with open("fuzzer/debug/{}_{}.out".format(self.file_name, i), 'w') as f: with open("fuzzer/debug/{}_{}.out".format(self.file_name, i), 'w') as f:
f.write(pretty) f.write(pretty)