Refactored ASTGenerator #3
|
@ -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
|
||||||
|
|
14
config.yaml
14
config.yaml
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue