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 = (
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):
names = get_english_words_set(['web2'], alpha=True)
possible_names = filter(lambda x: self.settings['properties']['id-length']['max'] <= len(x) <=
@ -575,6 +584,8 @@ class AstGenerator:
self.generate_comp_expr()
elif expr_type == GAZ_CHAR_KEY:
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
ty = self.get_type(GAZ_RHS_TAG)
self.generate_expression(ty)
@ -703,6 +714,7 @@ class AstGenerator:
name = ''.join(random.choices(string.ascii_letters, k=length))
return name
else:
try:
if name_type == GAZ_VAR_TAG:
choice = random.choice(self.variable_names)
self.variable_names.remove(choice)
@ -711,24 +723,44 @@ class AstGenerator:
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): # TODO Add support for composite types
return 'int' # TODO Add support for all types
if tag in [GAZ_PROCEDURE_TAG, GAZ_FUNCTION_TAG, GAZ_VAR_TAG]:
cutoffs = []
values = []
types = []
for key, value in self.settings["type-weights"]["value-types"].items():
if key == GAZ_VOID_TYPE and tag != GAZ_PROCEDURE_TAG:
continue
cutoffs.append(value + sum(cutoffs))
values.append(value)
types.append(key)
def get_type(self, tag) -> str: # TODO Add support for composite types
"""
@brief get a random type from the list of possible types
res = random.randint(0, sum(values))
@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
else:
return self.get_type(tag)
else:
return choice
def get_choice(self, options, numline, cutoffs):
res = random.randint(0, numline - 1)
for i in range(len(cutoffs)):
if res < cutoffs[i]:
return types[i]
try:
return options[i]
except Exception as e:
raise ValueError(str(e) + "Internal Error, please report the stack trace to me")
### LOOP HELPERS ###
@ -848,7 +880,7 @@ class AstGenerator:
if cutoffs[i] < a < cutoffs[i + 1]:
try:
options[i]()
except KeyError:
except KeyError: # if the key is not in the options (due to exclusion)
continue
except ValueError:
break

View file

@ -9,7 +9,7 @@ generation-options:
max-globals: 5 # maximum number of global variables
properties:
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
min: 1
max: 5
@ -68,12 +68,12 @@ statement-weights: # set to 0 for any statements y
in-stream: 5
type-weights:
value-types:
integer: 50
real: 50
boolean: 50
character: 50
void: 10
atomic-types:
int: 50 # TODO change these to the gaz types
float: 50
bool: 50
char: 50
void: 0 # TODO add support for void
composite-types:
vector: 20
tuple: 5

View file

@ -47,6 +47,12 @@ GAZ_STRING_KEY = "string"
GAZ_CHAR_KEY = "char"
GAZ_BRACKET_TAG = "brackets"
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):