def try_to_find_var_and_set_it(self, var: Identifier, evaluated_value): # Current scope should not be the outer scope if self.parent_scope is None: raise Exception # We are allowed to change var in the global scope if var.get_name() in self.symbol_table: self.symbol_table[var.get_name()] = evaluated_value return True return False
def try_to_find_var_and_set_it(self, var: Identifier, evaluated_value): # Check if var is in the current scope. # If it's not check in the parent scope. # Function stops calling itself when var is found and set # or when it reaches global scope where it is stopped. # Returns True if found and set var in current scope. # Otherwise returns what parent returned. if var.get_name() in self.symbol_table: self.symbol_table[var.get_name()] = evaluated_value return True return self.parent_scope.try_to_find_var_and_set_it( var, evaluated_value)
def get_var(self, var: Identifier): # Loop through all parent scopes (including current scope) # and return first matched variable or None if not found. scope = self while (value := scope.symbol_table.get(var.get_name(), None)) is None\ and scope.parent_scope is not None: scope = scope.parent_scope
def set_var(self, var: Identifier, evaluated_value): # To set variable means that # the variable got assigned. # First check if the variable exists # in one of the parent scopes and if it does, reassign it. # If it doesn't, add it to the symbol table of this scope. if not self.try_to_find_var_and_set_it(var, evaluated_value): self.symbol_table[var.get_name()] = evaluated_value
def make_generic_parameters(self, arguments): parameters = [] if len(arguments) > MAX_GENERIC_PARAMETERS: return None if isinstance(self.statement, BuiltinFunction): self.statement.set_parameter_list(parameters) # chr(97) == 'a' for i in range(len(arguments)): parameters.append(Identifier(chr(97+i))) return parameters
def create_expected_binary_operator(parameters): binop = None actions = { 'scalar': lambda value: Scalar(value), 'op': lambda type: Token(TokenType(type)), 'id': lambda id: Identifier(id), 'prev': lambda _: binop } for param in parameters: if param[1][1] == '=': binop = Assignment(actions[param[0][0]](param[0][1]), actions[param[2][0]](param[2][1])) else: binop = BinaryOperator( lvalue=actions[param[0][0]](param[0][1]), op=actions[param[1][0]](param[1][1]), rvalue=actions[param[2][0]](param[2][1]) ) return binop
class Transpose(BuiltinFunction): name = 'transpose' parameter_list = [Identifier('a')] def get_parameters(self): return self.parameter_list[0]
class Shape(BuiltinFunction): name = 'shape' parameter_list = [Identifier('a')] def get_parameters(self): return self.parameter_list[0]
class Round(BuiltinFunction): name = 'round' parameter_list = [Identifier('a')] def get_parameters(self): return self.parameter_list[0]
class Min(BuiltinFunction): name = 'min' parameter_list = [Identifier('a'), Identifier('b')] def get_parameters(self): return self.parameter_list[0], self.parameter_list[1]
class Len(BuiltinFunction): name = 'len' parameter_list = [Identifier('a')] def get_parameters(self): return self.parameter_list[0]
def get_wrapped_fun(self): return (Identifier(self.name), self.parameter_list, self)