Fixed error that when assignments fail they still leave their tag
Took 39 minutes
This commit is contained in:
parent
5e5d6aeba9
commit
4ee1770092
|
@ -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]:
|
||||||
|
try:
|
||||||
options[i]()
|
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):
|
||||||
|
if mut is None:
|
||||||
return Variable(self.get_name(GAZ_VAR_TAG), var_type, self.get_qualifier())
|
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 = [
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue