Refactor and bugfix for integer division
Took 54 minutes
This commit is contained in:
parent
561a9a5efa
commit
fb36aef06e
|
@ -55,10 +55,30 @@ class AstGenerator:
|
||||||
self.int_op_options, self.int_op_cutoffs, self.int_op_numline = (
|
self.int_op_options, self.int_op_cutoffs, self.int_op_numline = (
|
||||||
self.get_numberlines('expression-weights',
|
self.get_numberlines('expression-weights',
|
||||||
['brackets', 'arithmetic', 'unary'],
|
['brackets', 'arithmetic', 'unary'],
|
||||||
[[], [], ['negation']]))
|
[[], [], ['not']]))
|
||||||
self.int_unary = ['negation', 'noop']
|
self.int_unary = ['negation', 'noop']
|
||||||
|
|
||||||
pass
|
self.bool_op_options, self.bool_op_cutoffs, self.bool_op_numline = (
|
||||||
|
self.get_numberlines('expression-weights',
|
||||||
|
['comparison', 'logical', 'brackets', 'unary'],
|
||||||
|
[['less-than-or-equal', 'greater-than-or-equal', 'less-than', 'greater-than'], [], [], ['noop', 'negation']]))
|
||||||
|
self.bool_unary = ['not']
|
||||||
|
|
||||||
|
self.float_op_options, self.float_op_cutoffs, self.float_op_numline = (
|
||||||
|
self.get_numberlines('expression-weights',
|
||||||
|
['brackets', 'arithmetic', 'unary'],
|
||||||
|
[[], [], ['not']]))
|
||||||
|
self.float_unary = ['negation', 'noop']
|
||||||
|
|
||||||
|
self.char_op_options, self.char_op_cutoffs, self.char_op_numline = (
|
||||||
|
self.get_numberlines('expression-weights',
|
||||||
|
['brackets', 'comparison'],
|
||||||
|
[[], ['less-than', 'greater-than', 'less-than-or-equal', 'greater-than-or-equal']]))
|
||||||
|
|
||||||
|
self.comp_op_options, self.comp_op_cutoffs, self.comp_op_numline = (
|
||||||
|
self.get_numberlines('expression-weights',
|
||||||
|
['brackets', 'comparison'],
|
||||||
|
[[], []]))
|
||||||
|
|
||||||
def get_numberlines(self, settings_section: str, subsettings: list[str], excluded_values: list[list[str or None]]):
|
def get_numberlines(self, settings_section: str, subsettings: list[str], excluded_values: list[list[str or None]]):
|
||||||
assert len(subsettings) == len(excluded_values)
|
assert len(subsettings) == len(excluded_values)
|
||||||
|
@ -242,49 +262,42 @@ class AstGenerator:
|
||||||
break
|
break
|
||||||
break
|
break
|
||||||
|
|
||||||
def generate_int_real_expr(self):
|
def generate_int_expr(self):
|
||||||
# Number line
|
self._generate_expression([GAZ_INT_KEY],
|
||||||
number_line = 100
|
self.int_op_numline,
|
||||||
cutoffs = [10, 30, 50, 80, 100]
|
self.int_op_cutoffs,
|
||||||
options = { #TODO add brackets
|
self.int_op_options,
|
||||||
0: "addition",
|
self.int_unary)
|
||||||
1: "subtraction",
|
|
||||||
2: "multiplication",
|
|
||||||
3: "division",
|
|
||||||
4: "modulo",
|
|
||||||
5: "power",
|
|
||||||
6: "negation",
|
|
||||||
7: "noop",
|
|
||||||
8: "equality",
|
|
||||||
9: "inequality",
|
|
||||||
10: "less-than",
|
|
||||||
11: "greater-than",
|
|
||||||
12: "less-than-or-equal",
|
|
||||||
13: "greater-than-or-equal",
|
|
||||||
}
|
|
||||||
|
|
||||||
unary = ["negation", "noop"]
|
def generate_float_expr(self):
|
||||||
|
self._generate_expression([GAZ_FLOAT_KEY, GAZ_INT_KEY],
|
||||||
self._generate_expression([GAZ_INT_KEY, GAZ_FLOAT_KEY], self.int_op_numline, self.int_op_cutoffs,
|
self.float_op_numline,
|
||||||
self.int_op_options, self.int_unary)
|
self.float_op_cutoffs,
|
||||||
|
self.float_op_options,
|
||||||
|
self.float_unary)
|
||||||
|
|
||||||
def generate_bool_expr(self):
|
def generate_bool_expr(self):
|
||||||
# Number line
|
self._generate_expression([GAZ_BOOL_KEY],
|
||||||
number_line = 100
|
self.bool_op_numline,
|
||||||
cutoffs = [10, 30, 50, 80, 100]
|
self.bool_op_cutoffs,
|
||||||
options = { #TODO add brackets # TODO cannot guarantee correctness of comparison since booleans may appear
|
self.bool_op_options,
|
||||||
0: "equality",
|
self.bool_unary)
|
||||||
1: "and",
|
|
||||||
2: "or",
|
|
||||||
3: "xor",
|
|
||||||
4: "not",
|
|
||||||
}
|
|
||||||
|
|
||||||
unary = ["not"]
|
def generate_char_expr(self):
|
||||||
|
self._generate_expression([GAZ_CHAR_KEY],
|
||||||
|
self.char_op_numline,
|
||||||
|
self.char_op_cutoffs,
|
||||||
|
self.char_op_options)
|
||||||
|
|
||||||
self._generate_expression([GAZ_BOOL_KEY], number_line, cutoffs, options, unary)
|
def generate_comp_expr(self):
|
||||||
|
self._generate_expression([GAZ_BOOL_KEY],
|
||||||
|
self.comp_op_numline,
|
||||||
|
self.comp_op_cutoffs,
|
||||||
|
self.comp_op_options,
|
||||||
|
comparison=True)
|
||||||
|
|
||||||
def _generate_expression(self, expr_type: list[str], number_line, cutoffs, options, unary=None):
|
def _generate_expression(self, expr_type: list[str], number_line,
|
||||||
|
cutoffs, options, unary=None, comparison: bool = False):
|
||||||
if unary is None:
|
if unary is None:
|
||||||
unary = []
|
unary = []
|
||||||
|
|
||||||
|
@ -293,7 +306,7 @@ class AstGenerator:
|
||||||
|
|
||||||
if self.current_nesting_depth > self.settings['generation-options']['max-nesting-depth'] or random.random() < \
|
if self.current_nesting_depth > self.settings['generation-options']['max-nesting-depth'] or random.random() < \
|
||||||
self.settings['block-termination-probability']:
|
self.settings['block-termination-probability']:
|
||||||
self.generate_literal(random.choice(expr_type)) # TODO add the reals
|
self.generate_literal(random.choice(expr_type))
|
||||||
self.current_nesting_depth -= 1
|
self.current_nesting_depth -= 1
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -511,11 +524,11 @@ class AstGenerator:
|
||||||
|
|
||||||
def generate_expression(self, expr_type: str):
|
def generate_expression(self, expr_type: str):
|
||||||
if expr_type == GAZ_INT_KEY or expr_type == GAZ_FLOAT_KEY:
|
if expr_type == GAZ_INT_KEY or expr_type == GAZ_FLOAT_KEY:
|
||||||
self.generate_int_real_expr()
|
self.generate_int_expr()
|
||||||
elif expr_type == GAZ_BOOL_KEY:
|
elif expr_type == GAZ_BOOL_KEY:
|
||||||
self.generate_bool_expr()
|
self.generate_bool_expr()
|
||||||
elif expr_type == ANY_TYPE: # TODO implement the choice of any type
|
elif expr_type == ANY_TYPE: # TODO implement the choice of any type
|
||||||
self.generate_int_real_expr()
|
self.generate_int_expr()
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(f"Expression type {expr_type} not implemented")
|
raise NotImplementedError(f"Expression type {expr_type} not implemented")
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ class TestGeneration(unittest.TestCase):
|
||||||
# print("iteration: " + str(l))
|
# print("iteration: " + str(l))
|
||||||
self.ast_gen.ast = ET.Element("block")
|
self.ast_gen.ast = ET.Element("block")
|
||||||
self.ast_gen.current_ast_element = self.ast_gen.ast
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
self.ast_gen.generate_int_real_expr()
|
self.ast_gen.generate_int_expr()
|
||||||
# self.write_ast()
|
# self.write_ast()
|
||||||
|
|
||||||
if self.ast_gen.ast.find("operator") is None:
|
if self.ast_gen.ast.find("operator") is None:
|
||||||
|
|
|
@ -82,7 +82,7 @@ class GazUnparser(GeneralUnparser):
|
||||||
else:
|
else:
|
||||||
return str(val)
|
return str(val)
|
||||||
|
|
||||||
def translate_op(self, param):
|
def translate_op(self, param, ty=None):
|
||||||
return to_gaz_op(param)
|
return to_gaz_op(param)
|
||||||
|
|
||||||
def translate_type(self, ty):
|
def translate_type(self, ty):
|
||||||
|
|
|
@ -171,8 +171,9 @@ class GeneralUnparser:
|
||||||
self.unparse_node(child)
|
self.unparse_node(child)
|
||||||
|
|
||||||
def unparse_operator(self, node):
|
def unparse_operator(self, node):
|
||||||
|
ty = node.get(GAZ_TY_KEY)
|
||||||
self.unparse_xhs(node.find(GAZ_LHS_TAG))
|
self.unparse_xhs(node.find(GAZ_LHS_TAG))
|
||||||
self.source += " {} ".format(self.translate_op(node.get("op")))
|
self.source += " {} ".format(self.translate_op(node.get("op"), ty))
|
||||||
self.unparse_xhs(node.find(GAZ_RHS_TAG))
|
self.unparse_xhs(node.find(GAZ_RHS_TAG))
|
||||||
|
|
||||||
def unparse_return(self, node):
|
def unparse_return(self, node):
|
||||||
|
@ -304,7 +305,7 @@ class GeneralUnparser:
|
||||||
def translate_value(self, val):
|
def translate_value(self, val):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def translate_op(self, param):
|
def translate_op(self, param, ty=None):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def translate_type(self, ty):
|
def translate_type(self, ty):
|
||||||
|
|
|
@ -21,15 +21,17 @@ def to_python_type(ty):
|
||||||
raise Exception("Unknown type: " + ty)
|
raise Exception("Unknown type: " + ty)
|
||||||
|
|
||||||
|
|
||||||
def to_python_op(param):
|
def to_python_op(param, ty):
|
||||||
if param == "negation" or param == "subtraction":
|
if param == "negation" or param == "subtraction":
|
||||||
return "-"
|
return "-"
|
||||||
elif param == "addition" or param == "noop":
|
elif param == "addition" or param == "noop":
|
||||||
return "+"
|
return "+"
|
||||||
elif param == "multiplication":
|
elif param == "multiplication":
|
||||||
return "*"
|
return "*"
|
||||||
elif param == "division":
|
elif param == "division" and ty != GAZ_INT_KEY:
|
||||||
return "/"
|
return "/"
|
||||||
|
elif param == "division" and ty == GAZ_INT_KEY:
|
||||||
|
return "//"
|
||||||
elif param == "modulo":
|
elif param == "modulo":
|
||||||
return "%"
|
return "%"
|
||||||
elif param == "power":
|
elif param == "power":
|
||||||
|
@ -79,8 +81,8 @@ class PythonUnparser(GeneralUnparser):
|
||||||
def translate_value(self, val):
|
def translate_value(self, val):
|
||||||
return str(val)
|
return str(val)
|
||||||
|
|
||||||
def translate_op(self, param):
|
def translate_op(self, param, ty=None):
|
||||||
return to_python_op(param)
|
return to_python_op(param, ty)
|
||||||
|
|
||||||
def translate_type(self, ty):
|
def translate_type(self, ty):
|
||||||
return to_python_type(ty)
|
return to_python_type(ty)
|
||||||
|
|
|
@ -17,7 +17,7 @@ properties:
|
||||||
number-of-arguments: # number of arguments to a routine
|
number-of-arguments: # number of arguments to a routine
|
||||||
min: 1
|
min: 1
|
||||||
max: 10
|
max: 10
|
||||||
generate-max-int: True # if False, generate integers between [-1000, 1000] else
|
generate-max-int: False # if False, generate integers between [-1000, 1000] else
|
||||||
expression-weights: # weights for expressions
|
expression-weights: # weights for expressions
|
||||||
# the higher a weight, the more likely (0, 10000), 0 to exclude, 10000 for only that
|
# the higher a weight, the more likely (0, 10000), 0 to exclude, 10000 for only that
|
||||||
brackets: 10
|
brackets: 10
|
||||||
|
|
Loading…
Reference in a new issue