Refactored ASTGenerator #3

Merged
aCompetentBean merged 8 commits from ayrton/refactor into main 2023-11-24 07:34:47 -07:00
3 changed files with 69 additions and 31 deletions
Showing only changes of commit 5f6b7ab53b - Show all commits

View file

@ -73,6 +73,15 @@ class AstGenerator:
self.comp_op_options, self.comp_op_cutoffs, self.comp_op_numline = ( self.comp_op_options, self.comp_op_cutoffs, self.comp_op_numline = (
get_numberlines('expression-weights', ['brackets', 'comparison'], [[], []], self.settings)) get_numberlines('expression-weights', ['brackets', 'comparison'], [[], []], self.settings))
self.type_options, self.type_cutoffs, self.type_numline = (
get_numberlines('type-weights', ['composite', 'atomic'], [[], []], self.settings))
self.atomic_type_options, self.atomic_type_cutoffs, self.atomic_type_numline = (
get_numberlines('type-weights', ['atomic-types'], [[]], self.settings))
self.composite_type_options, self.composite_type_cutoffs, self.composite_type_numline = (
get_numberlines('type-weights', ['composite-types'], [[]], self.settings))
def _init_names(self): def _init_names(self):
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) <=
@ -575,6 +584,8 @@ class AstGenerator:
self.generate_comp_expr() self.generate_comp_expr()
elif expr_type == GAZ_CHAR_KEY: elif expr_type == GAZ_CHAR_KEY:
self.generate_char_expr() self.generate_char_expr()
elif expr_type == GAZ_FLOAT_KEY:
self.generate_float_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
ty = self.get_type(GAZ_RHS_TAG) ty = self.get_type(GAZ_RHS_TAG)
self.generate_expression(ty) self.generate_expression(ty)
@ -703,32 +714,53 @@ class AstGenerator:
name = ''.join(random.choices(string.ascii_letters, k=length)) name = ''.join(random.choices(string.ascii_letters, k=length))
return name return name
else: else:
if name_type == GAZ_VAR_TAG: try:
choice = random.choice(self.variable_names) if name_type == GAZ_VAR_TAG:
self.variable_names.remove(choice) choice = random.choice(self.variable_names)
self.variable_names.remove(choice)
return choice
else:
choice = random.choice(self.routine_names)
self.routine_names.remove(choice)
return choice
except IndexError: # if we run out of variable names
length = random.randint(self.settings['properties']['id-length']['min'],
self.settings['properties']['id-length']['max'])
name = ''.join(random.choices(string.ascii_letters, k=length))
return name
def get_type(self, tag) -> str: # TODO Add support for composite types
"""
@brief get a random type from the list of possible types
@param tag:
@return: a type as a string
"""
comp_atom = self.get_choice(self.type_options, self.type_numline, self.type_cutoffs)
choice = ""
if comp_atom == GAZ_ATOMIC_TYPE_KEY:
choice = self.get_choice(self.atomic_type_options, self.atomic_type_numline, self.atomic_type_cutoffs)
elif comp_atom == GAZ_COMPOSITE_TYPE_KEY:
choice = self.get_choice(self.composite_type_options, self.composite_type_numline, self.composite_type_cutoffs)
else:
raise NotImplementedError(f"Unimplemented generator for type: {comp_atom}")
if tag not in [GAZ_PROCEDURE_TAG]:
if choice != GAZ_VOID_TYPE:
return choice return choice
else: else:
choice = random.choice(self.routine_names) return self.get_type(tag)
self.routine_names.remove(choice) else:
return choice return choice
def get_type(self, tag): # TODO Add support for composite types def get_choice(self, options, numline, cutoffs):
return 'int' # TODO Add support for all types res = random.randint(0, numline - 1)
if tag in [GAZ_PROCEDURE_TAG, GAZ_FUNCTION_TAG, GAZ_VAR_TAG]: for i in range(len(cutoffs)):
cutoffs = [] if res < cutoffs[i]:
values = [] try:
types = [] return options[i]
for key, value in self.settings["type-weights"]["value-types"].items(): except Exception as e:
if key == GAZ_VOID_TYPE and tag != GAZ_PROCEDURE_TAG: raise ValueError(str(e) + "Internal Error, please report the stack trace to me")
continue
cutoffs.append(value + sum(cutoffs))
values.append(value)
types.append(key)
res = random.randint(0, sum(values))
for i in range(len(cutoffs)):
if res < cutoffs[i]:
return types[i]
### LOOP HELPERS ### ### LOOP HELPERS ###
@ -848,7 +880,7 @@ class AstGenerator:
if cutoffs[i] < a < cutoffs[i + 1]: if cutoffs[i] < a < cutoffs[i + 1]:
try: try:
options[i]() options[i]()
except KeyError: except KeyError: # if the key is not in the options (due to exclusion)
continue continue
except ValueError: except ValueError:
break break

View file

@ -9,7 +9,7 @@ generation-options:
max-globals: 5 # maximum number of global variables max-globals: 5 # maximum number of global variables
properties: properties:
max-range-length: 5 # maximum length of ranges, vectors and tuples, (AxA matrices can exist) max-range-length: 5 # maximum length of ranges, vectors and tuples, (AxA matrices can exist)
use-english-words: True # use english words instead of random names (this may limit the maximum number of names) use-english-words: True # use english words instead of random names (if we run out, we switch to random)
id-length: # length of identifiers id-length: # length of identifiers
min: 1 min: 1
max: 5 max: 5
@ -68,12 +68,12 @@ statement-weights: # set to 0 for any statements y
in-stream: 5 in-stream: 5
type-weights: type-weights:
value-types: atomic-types:
integer: 50 int: 50 # TODO change these to the gaz types
real: 50 float: 50
boolean: 50 bool: 50
character: 50 char: 50
void: 10 void: 0 # TODO add support for void
composite-types: composite-types:
vector: 20 vector: 20
tuple: 5 tuple: 5

View file

@ -47,6 +47,12 @@ GAZ_STRING_KEY = "string"
GAZ_CHAR_KEY = "char" GAZ_CHAR_KEY = "char"
GAZ_BRACKET_TAG = "brackets" GAZ_BRACKET_TAG = "brackets"
GAZ_BREAK_TAG = "break" GAZ_BREAK_TAG = "break"
GAZ_ATOMIC_TYPE_KEY = "atomic"
GAZ_COMPOSITE_TYPE_KEY = "composite"
GAZ_COMPOSITE_KEY = "composite"
GAZ_VECTOR_KEY = "vector"
GAZ_TUPLE_KEY = "tuple"
GAZ_MATRIX_KEY = "matrix"
class NoneTagException(Exception): class NoneTagException(Exception):