Skip to content

Commit

Permalink
Fix classical array symbol usage
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrieleMessina authored Nov 1, 2024
1 parent 6f9a8a6 commit c976526
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 27 deletions.
8 changes: 6 additions & 2 deletions src/grammar_frontend/literal.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@ def visitTermList(self, ctx:qutes_parser.TermListContext) -> list[Symbol]:
def visitArray(self, ctx:qutes_parser.ArrayContext) -> list[Symbol]:
terms:list[Symbol] = self.visit(ctx.termList())
for term in terms:
self.variables_handler.delete_variable(term)
if(term.is_anonymous):
self.variables_handler.delete_variable(term)
array_type = QutesDataType.promote_unit_to_array_type(terms[0].symbol_declaration_static_type) #TODO: check if all elements are of the same type
unit_type = QutesDataType.get_unit_class_from_array_type(array_type)
array_symbol = self.variables_handler.declare_anonymous_variable(array_type, QuantumArrayType(unit_type, terms), ctx.start.tokenIndex)
if(QutesDataType.is_quantum_type(array_type)):
array_symbol = self.variables_handler.declare_anonymous_variable(array_type, QuantumArrayType(unit_type, terms), ctx.start.tokenIndex)
else:
array_symbol = self.variables_handler.declare_anonymous_variable(array_type, terms, ctx.start.tokenIndex)
return array_symbol

def visitVariableType(self, ctx:qutes_parser.VariableTypeContext):
Expand Down
5 changes: 4 additions & 1 deletion src/grammar_frontend/statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ def visitForeachStatement(self, ctx:qutes_parser.ForeachStatementContext):
if(ctx.variableName(1)):
index = self.variables_handler.get_variable_symbol(self.visit(ctx.variableName(1)), ctx.start.tokenIndex)

array = self.visit(ctx.qualifiedName()).value.array
array = self.visit(ctx.qualifiedName()).value
if(isinstance(array, QuantumArrayType)):
array = array.array

if(array != None):
for i, next_value in enumerate(array):
self.scope_handler.restart_visiting_cycle_scope()
Expand Down
13 changes: 1 addition & 12 deletions src/symbols/types/qutes_data_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ def type_of(var_value : any) -> 'QutesDataType':
if isinstance(var_value, list):
if(len(var_value) == 0):
return QutesDataType.bool_array
bigger_type = QutesDataType.types_are_compatible([QutesDataType.type_of(item) for item in var_value])
return QutesDataType.promote_unit_to_array_type(bigger_type)
return QutesDataType.promote_unit_to_array_type(QutesDataType.type_of(var_value[0]))
if isinstance(var_value, QuantumArrayType):
if var_value.unit_type == Qubit:
return QutesDataType.qubit_array
Expand All @@ -77,16 +76,6 @@ def type_of(var_value : any) -> 'QutesDataType':
if isinstance(var_value, Symbol):
return var_value.symbol_declaration_static_type
return QutesDataType.undefined

def types_are_compatible(types: list['QutesDataType']) -> 'QutesDataType':
if len(types) == 0:
return QutesDataType.bool
if len(types) == 1:
return types[0]
if all(type == types[0] for type in types):
return types[0]
# TODO: if not all types are the same, check if they can be promoted to a common type
raise TypeError(f"Types {types} are not compatible.")

def from_string_type(var_definition_type : str) -> 'QutesDataType':
to_match = var_definition_type.lower()
Expand Down
37 changes: 27 additions & 10 deletions src/symbols/types/type_casting_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __init__(self, quantum_circuit_handler : 'QuantumCircuitHandler'):
QutesDataType.qustring_array: [QutesDataType.qustring_array],
}

def promote_value_to_type(self, var_value : any, from_type:'QutesDataType', to_type : 'QutesDataType', symbol_or_literal) -> any:
def promote_value_to_type(self, var_value : any, from_type:'QutesDataType', to_type : 'QutesDataType') -> any:
match to_type:
case QutesDataType.bool:
return bool(int(var_value))
Expand All @@ -68,25 +68,25 @@ def promote_value_to_type(self, var_value : any, from_type:'QutesDataType', to_t
case QutesDataType.qustring:
return Qustring.fromValue(var_value)
case QutesDataType.bool_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.bool) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.bool) for symbol in var_value]
case QutesDataType.int_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.int) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.int) for symbol in var_value]
case QutesDataType.float_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.float) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.float) for symbol in var_value]
case QutesDataType.string_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.string) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.string) for symbol in var_value]
case QutesDataType.qubit_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.qubit) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.qubit) for symbol in var_value]
case QutesDataType.quint_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.quint) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.quint) for symbol in var_value]
case QutesDataType.qustring_array:
return [self.promote_value_to_type(value, QutesDataType.type_of(value), QutesDataType.qustring) for value in var_value]
return [self.promote_value_to_type(symbol.value, QutesDataType.type_of(symbol.value), QutesDataType.qustring) for symbol in var_value]
case _:
return QutesDataType.undefined

def __cast_value_to_type(self, var_value : any, from_type:'QutesDataType', to_type : 'QutesDataType') -> any:
if self.type_promotable_to[to_type].count(from_type) > 0:
return self.promote_value_to_type(var_value, from_type, to_type, None)
return self.promote_value_to_type(var_value, from_type, to_type)
if self.type_down_castable_to[to_type].count(from_type) > 0:
return self.down_cast_value_to_type(var_value, from_type, to_type, None)
raise TypeError(f"Cannot cast type '{from_type}' to '{to_type}'.")
Expand Down Expand Up @@ -145,4 +145,21 @@ def down_cast_value_to_type(self, var_value : any, from_type:'QutesDataType', to
case QutesDataType.qustring_array:
return [self.down_cast_value_to_type(value, QutesDataType.type_of(value), QutesDataType.qustring, value) for value in var_value]
case _:
return QutesDataType.undefined
return QutesDataType.undefined

#TODO: use this method to check if a type can be casted to another type
def types_are_compatible(types: list[QutesDataType]) -> QutesDataType:
types = list(set(types))
if len(types) == 0:
return QutesDataType.bool
if len(types) == 1:
return types[0]
if all(type == types[0] for type in types):
return types[0]
# if not all types are the same, check if they can be promoted to a common type
else:
# for each type, check if all elements can be casted to that type
for type in types:
if all((type in TypeCastingHandler.type_promotable_to[other_type]) or (type in TypeCastingHandler.type_down_castable_to[other_type]) for other_type in types):
return type
raise TypeError(f"Types {types} are not compatible.")
5 changes: 3 additions & 2 deletions src/symbols/variables_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def update_variable_state(self, variable_name : str, new_state) -> Symbol:
if(value_to_assign_qutes_type != definition_qutes_type):
# promote the current data type if needed.
if(promoted_type != QutesDataType.undefined):
value_to_assign = self.type_casting_handler.promote_value_to_type(value_to_assign, value_to_assign_qutes_type, promoted_type, new_state)
value_to_assign = self.type_casting_handler.promote_value_to_type(value_to_assign, value_to_assign_qutes_type, promoted_type)
final_type = promoted_type
elif(down_cast_type != QutesDataType.undefined):
value_to_assign = self.type_casting_handler.down_cast_value_to_type(value_to_assign, value_to_assign_qutes_type, down_cast_type, new_state)
Expand Down Expand Up @@ -83,6 +83,7 @@ def declare_variable(self, declaration_type : QutesDataType, variable_name : str
def declare_anonymous_variable(self, declaration_type : QutesDataType, value, ast_token_index:int) -> Symbol:
return self.declare_variable(declaration_type, f"{QuantumCircuitHandler.anon_variable_name_prefix}_{next(QuantumCircuitHandler.anon_counter)}", ast_token_index, value, True)

# TODO: check who is calling this method and why.
def delete_variable(self, symbol:Symbol) -> None:
if symbol in self.scope_handler.current_symbols_scope.symbols:
self.scope_handler.current_symbols_scope.symbols.remove(symbol)
Expand All @@ -108,7 +109,7 @@ def create_symbol(self, qutes_type : QutesDataType, value, ast_token_index:int)
if(value_qutes_type != definition_type):
# promote the current data type if needed.
if(promoted_type != QutesDataType.undefined):
value = self.type_casting_handler.promote_value_to_type(value, value_qutes_type, promoted_type, None)
value = self.type_casting_handler.promote_value_to_type(value, value_qutes_type, promoted_type)
final_type = promoted_type
elif(down_cast_type != QutesDataType.undefined):
value = self.type_casting_handler.down_cast_value_to_type(value, value_qutes_type, down_cast_type, None)
Expand Down

0 comments on commit c976526

Please sign in to comment.