Refactor and bugfix for integer division

Took 54 minutes
This commit is contained in:
ayrton 2023-11-21 21:39:04 -07:00
parent 561a9a5efa
commit fb36aef06e
6 changed files with 67 additions and 51 deletions

View file

@ -55,10 +55,30 @@ class AstGenerator:
self.int_op_options, self.int_op_cutoffs, self.int_op_numline = (
self.get_numberlines('expression-weights',
['brackets', 'arithmetic', 'unary'],
[[], [], ['negation']]))
[[], [], ['not']]))
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]]):
assert len(subsettings) == len(excluded_values)
@ -242,49 +262,42 @@ class AstGenerator:
break
break
def generate_int_real_expr(self):
# Number line
number_line = 100
cutoffs = [10, 30, 50, 80, 100]
options = { #TODO add brackets
0: "addition",
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",
}
def generate_int_expr(self):
self._generate_expression([GAZ_INT_KEY],
self.int_op_numline,
self.int_op_cutoffs,
self.int_op_options,
self.int_unary)
unary = ["negation", "noop"]
self._generate_expression([GAZ_INT_KEY, GAZ_FLOAT_KEY], self.int_op_numline, self.int_op_cutoffs,
self.int_op_options, self.int_unary)
def generate_float_expr(self):
self._generate_expression([GAZ_FLOAT_KEY, GAZ_INT_KEY],
self.float_op_numline,
self.float_op_cutoffs,
self.float_op_options,
self.float_unary)
def generate_bool_expr(self):
# Number line
number_line = 100
cutoffs = [10, 30, 50, 80, 100]
options = { #TODO add brackets # TODO cannot guarantee correctness of comparison since booleans may appear
0: "equality",
1: "and",
2: "or",
3: "xor",
4: "not",
}
self._generate_expression([GAZ_BOOL_KEY],
self.bool_op_numline,
self.bool_op_cutoffs,
self.bool_op_options,
self.bool_unary)
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:
unary = []
@ -293,7 +306,7 @@ class AstGenerator:
if self.current_nesting_depth > self.settings['generation-options']['max-nesting-depth'] or random.random() < \
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
return
@ -511,11 +524,11 @@ class AstGenerator:
def generate_expression(self, expr_type: str):
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:
self.generate_bool_expr()
elif expr_type == ANY_TYPE: # TODO implement the choice of any type
self.generate_int_real_expr()
self.generate_int_expr()
else:
raise NotImplementedError(f"Expression type {expr_type} not implemented")

View file

@ -228,7 +228,7 @@ class TestGeneration(unittest.TestCase):
# print("iteration: " + str(l))
self.ast_gen.ast = ET.Element("block")
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()
if self.ast_gen.ast.find("operator") is None:

View file

@ -82,7 +82,7 @@ class GazUnparser(GeneralUnparser):
else:
return str(val)
def translate_op(self, param):
def translate_op(self, param, ty=None):
return to_gaz_op(param)
def translate_type(self, ty):

View file

@ -171,8 +171,9 @@ class GeneralUnparser:
self.unparse_node(child)
def unparse_operator(self, node):
ty = node.get(GAZ_TY_KEY)
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))
def unparse_return(self, node):
@ -304,7 +305,7 @@ class GeneralUnparser:
def translate_value(self, val):
raise NotImplementedError
def translate_op(self, param):
def translate_op(self, param, ty=None):
raise NotImplementedError
def translate_type(self, ty):

View file

@ -21,15 +21,17 @@ def to_python_type(ty):
raise Exception("Unknown type: " + ty)
def to_python_op(param):
def to_python_op(param, ty):
if param == "negation" or param == "subtraction":
return "-"
elif param == "addition" or param == "noop":
return "+"
elif param == "multiplication":
return "*"
elif param == "division":
elif param == "division" and ty != GAZ_INT_KEY:
return "/"
elif param == "division" and ty == GAZ_INT_KEY:
return "//"
elif param == "modulo":
return "%"
elif param == "power":
@ -79,8 +81,8 @@ class PythonUnparser(GeneralUnparser):
def translate_value(self, val):
return str(val)
def translate_op(self, param):
return to_python_op(param)
def translate_op(self, param, ty=None):
return to_python_op(param, ty)
def translate_type(self, ty):
return to_python_type(ty)

View file

@ -17,7 +17,7 @@ properties:
number-of-arguments: # number of arguments to a routine
min: 1
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
# the higher a weight, the more likely (0, 10000), 0 to exclude, 10000 for only that
brackets: 10