def wrapper(cls, name): print 'in verify_private_procedure for checking {}, for {}'.format( name.is_private, name.name) if name.is_private: if kwargs.get('suppress'): raise mylang_errors.VariableNotDeclared( "procedure '{}' not declared".format(name.name)) raise mylang_errors.PrivateVariableDeclaration( "procedure '{}' is private".format(name.name))
def variable_exists(self, var): if var.value.value not in self.variables: if var.value.value not in self.scopes: raise mylang_errors.VariableNotDeclared( "At line {}, near '{}': variable '{}' not declared".format( var.value.line_number, var.value.value, var.value.value)) return self.scopes[var.value.value] return self.variables[var.value.value]
def wrapper(cls, val_name): print 'val_name here', val_name if val_name in cls.private_variables: if kwargs.get('suppress'): raise mylang_errors.VariableNotDeclared( "Scope value '{}' not declared".format(val_name)) raise mylang_errors.PrivateVariableDeclaration( "Scope value '{}' is a private member variable".format( val_name)) return f(cls, val_name)
def parse_assign(self, line): operation_converters = { 'PLUS': lambda x, y: x + y, 'BAR': lambda x, y: x - y, 'STAR': lambda x, y: x * y, 'FORWARDSLASH': lambda x, y: x / y } current = next(line, None) if current.type == 'VARIABLE': test_final = next(line, None) if not test_final: if current.value.value not in self.variables: raise mylang_errors.VariableNotDeclared( "At line {}, '{}' not declared".format( current.value.line_number, current.value.value)) return self.variables[current.value.value] current.value.isValid(test_final.value) if test_final.type == 'DOT': path = collections.deque([current.value.value]) end_line = False last_seen = None while True: temp_path = next(line, None) if not temp_path: end_line = True break check = next(line, None) if not check: path.append(temp_path.value.value) break temp_path.value.isValid(check.value) if check.type in operation_converters: last_seen = check path.append(temp_path.value.value) break if temp_path.type == 'VARIABLE': path.append(temp_path.value.value) if temp_path.type in operation_converters: last_seen = temp_path break print 'self.scopes', self.scopes if path[0] not in self.scopes: raise mylang_errors.AttributeNotFound( "At line {}, near {}: variable '{}' has no attribute '{}'" .format(current.value.line_number, current.value.value, current.value.value, path[1])) scope_result = self.scopes while path: val = path.popleft() scope_result = scope_result[val] if last_seen: try: final_part = self.parse_assign(line) print 'scope_result', scope_result, type(scope_result) return operation_converters[last_seen.type]( scope_result, final_part) except: raise mylang_errors.IncompatableTypes( "Cannot {} value of type '{}' to type '{}'".format( { 'PLUS': 'contactinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[last_seen.type], type(scope_result).__name__, type(final_part).__name__)) print "scope_result", scope_result return scope_result ''' if test_final.type == 'PLUS': returned_val = self.parse_assign(line) return self.variables[current.value.value]+(string.ascii_lowercase+string.ascii_uppercase)[52%returned_val] if isinstance(returned_val, int) and isinstance(self.variables[current.value.value], str) else self.variables[current.value.value]+returned_val ''' if test_final.type in operation_converters: returned_val = self.parse_assign(line) if type(returned_val) != type( self.variables[current.value.value]): raise mylang_errors.IncompatableTypes( "At line {}, near {}, cannot {} variable of type '{}' to type '{}'" .format( current.value.line_number, current.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[test_final.type], type(self.variables[current.value.value]).__name__, type(returned_val).__name__)) return operation_converters[test_final.type]( self.variables[current.value.value], returned_val) if current.type == 'DIGIT': test_final = next(line, None) if not test_final: return int(current.value.value) current.value.isValid(test_final.value) ''' if test_final.type == 'PLUS': returned_val = self.parse_assign(line) if not isinstance(returned_val, int): raise mylang_errors.IncompatableTypes("At line {}, cannot concatinate type 'INT' to type {}".format(test_final.value.line_number, type(returned_val))) return int(current.value.value) + self.parse_assign(line) ''' if test_final.type in operation_converters: if test_final.type == 'STAR': second = next(line, None) print('second', second.value.value, current.value.value) if second.type != 'DIGIT': raise mylang_errors.IncompatableTypes( "At line {}, cannot multiply type 'INT' to type {}" .format(second.value.line_number, type(second.value.value).__name__)) operator = next(line, None) if not operator: return int(second.value.value) * int( current.value.value) returned_val = self.parse_assign(line) return operation_converters[operator.type]( int(current.value.value) * int(second.value.value), returned_val) returned_val = self.parse_assign(line) if type(returned_val) != type(int(current.value.value)): raise mylang_errors.IncompatableTypes( "At line {}, near {}, cannot {} variable of type 'INT' to type '{}'" .format( current.value.line_number, current.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[test_final.type], type(returned_val).__name__)) return operation_converters[test_final.type](int( current.value.value), returned_val) if current.type == 'STRING': test_final = next(line, None) if not test_final: return current.value.value[1:-1] current_line.value.isValid(test_final.value) if test_final.type == 'PLUS': returned_val = self.parse_assign(line) if not isinstance(returned_val, str) or not isinstance( returned_val, int): raise mylang_errors.IncompatableTypes( "At line {}, cannot concatinate type 'STRING' to type {}" .format(test_final.value.line_number, type(returned_val))) return current.value.value[1:-1] + ( string.ascii_lowercase + string.ascii_uppercase)[52 % returned_val] if isinstance( returned_val, int) else current.value.value[1:-1] + returned_val if test_final.type in operation_converters: raise mylang_errors.IncompatableTypes( "At line {}, cannot {} type 'string' to type '{}'".format( current.value.line_number, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[test_final.type], type(returned_val).__name__))
def parse_expression(self, line): operation_converters = { 'PLUS': lambda x, y: x + y, 'BAR': lambda x, y: x - y, 'STAR': lambda x, y: x * y, 'FORWARDSLASH': lambda x, y: x / y } current = next(line, None) print 'current here', current #print 'current here', current if not current: return None if current.type == 'VARIABLE': next_val = next(line, None) if not next_val or next_val.type == 'COMMA' or next_val.type == 'CPAREN' or next_val.type == 'CBRACKET': self.line = iter([next_val] + [i for i in line]) return self.variable_exists(current) current.value.isValid(next_val.value) if next_val.type == 'OPAREN': check_next_v = next(line, None) if not check_next_v: raise mylang_errors.ParameterSytnaxError( "At line {}, near '{}': reached unexpected end of procedure call" .format(current.value.line_number, current.value.value)) if check_next_v.type == 'CPAREN': if current.value.value not in self.procedures: raise mylang_errors.AttributeNotFound( "At line {}, near '{}': procedure '{}' not found". format(current.value.line_number, current.value.value, current.value.value)) result, namespace = self.procedures[current.value.value]() self.variables = namespace if namespace else self.variables check_last_v = next(line, None) if check_last_v.type in ['COMMA', 'CPAREN', 'CBRACKET']: self.line = iter([check_last_v] + [i for i in line]) return result if check_last_v.type in operation_converters: final_result = self.parse_expression(line) if type(result) != type(final_result): raise mylang_errors.IncompatableTypes( "At line {}, near '{}' cannot {} value of type '{}' to type '{}'" .format( check_last_v.value.line_number, check_last_v.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[check_last_v.type], type(result).__name__, type(final_result).__name__)) return operation_converters[check_last_v.type]( result, final_result) if current.value.value not in self.procedures: raise mylang_errors.VariableNotDeclared( "At line {}: procedure '{}' not declared".format( current.value.line_number, current.value.value)) self.line = iter([check_next_v] + [i for i in line]) params = [] while True: current_param = self.parse_expression(line) can_continue = next(line, None) params.append(current_param) if not can_continue or can_continue.type == 'CPAREN': break self.line = iter([can_continue] + [i for i in line]) print 'PARAMS HERE', params result, namespace = self.procedures[current.value.value]( *params) self.variables = namespace if namespace else self.variables checking_next_v = next(line, None) if not checking_next_v or checking_next_v.type in [ 'COMMA', 'CPAREN', 'CBRACKET' ]: self.line = iter([checking_next_v] + [i for i in line]) return result if checking_next_v.type in operation_converters: returned_result = self.parse_expression(line) if type(result) != type(returned_result): raise mylang_errors.IncompatableTypes( "At line {}, near '{}' cannot {} value of type '{}' to type '{}'" .format( checking_next_v.value.line_number, checking_next_v.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[checking_next_v.type], type(result).__name__, type(returned_result).__name__)) return operation_converters[checking_next_v.type]( result, returned_result) if next_val.type == 'DOT': path = [current.value.value] seen_operator = False while True: current_attr = next(line, None) if not current_attr: raise mylang_errors.InvalidAttributeCall( "At line {}, near '{}'".format( next_val.value.line_number, next_val.value.value)) if current_attr.type == 'VARIABLE': checking_next = next(line, None) if not checking_next: path.append(current_attr.value.value) break current_attr.value.isValid(checking_next.value) path.append(current_attr.value.value) if checking_next.type == 'OPAREN': method_params = [] while True: current_param = self.parse_expression(line) method_params.append(current_param) check_next_final = next(line, None) if not check_next_final or check_next_final.type == "CPAREN" or check_next_final.type == 'COMMA': break self.line = iter([check_next_final] + [i for i in line]) current_scope_selection = self.scopes if path[ 0] not in self.variables else self.variables path = list(path) the_method = path[-1] copy_path = list(copy.deepcopy(path)) start = path[0] path = path[:-1] while path: current_scope_selection = current_scope_selection[ path[0]] path = path[1:] Scope.private_procedure_check( current_scope_selection.procedures[the_method]) to_return, namespace = current_scope_selection.procedures[ the_method](*method_params) base = self.scopes if start not in self.variables else self.variables base[start].update_namespace(copy_path, namespace, start=start, end=copy_path[-1]) return to_return if checking_next.type in operation_converters or checking_next.type == 'CPAREN' or checking_next.type == 'COMMA' or checking_next.type == 'CBRACKET': seen_operator = None if ( checking_next.type == 'CPAREN' or checking_next.type == 'COMMA' or checking_next.type == 'CBRACKET') else checking_next.type self.line = iter([checking_next] + [i for i in line]) break start_scope = path[0] flag = False if start_scope not in self.scopes: if start_scope not in self.variables: raise mylang_errors.VariableNotDeclared( "Scope '{}' not declared".format(start_scope)) flag = True current_value_attr = self.scopes if not flag else self.variables while path: try: new_val = current_value_attr[path[0]] print 'in try block', new_val except: if path[0] not in current_value_attr.scopes: raise mylang_errors.AttributeNotFound( "At line {}, near '{}':scope '{}' has no attribute '{}'" .format(current_attr.value.line_number, current_attr.value.value, start_scope, path[0])) current_value_attr = current_value_attr.scopes[path[0]] path = path[1:] else: current_value_attr = new_val path = path[1:] if seen_operator: returned_val = self.parse_expression(line) if type(current_value_attr) != type(returned_val): raise mylang_errors.IncompatableTypes( "At line {}, near '{}': cannot {} value of type '{}' to type '{}'" .format( current_attr.value.line_number, current_attr.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[seen_operator], type(current_value_attr).__name__, type(returned_val).__name__)) return operation_converters[seen_operator]( current_value_attr, returned_val) return current_value_attr returned_val = self.parse_expression(line) if type(self.variables[current.value.value]) != type(returned_val): raise mylang_errors.IncompatableTypes( "At line {}, near '{}': cannot {} variable of type '{}' to type '{}'" .format( current.value.line_number, current.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[next_val.type], type(self.variables[current.value.value]).__name__, type(returned_val).__name__)) return operation_converters[next_val.type]( self.variables[current.value.value], returned_val) if current.type == 'DIGIT': next_val = next(line, None) if not next_val or next_val.type == 'COMMA' or next_val.type == 'CPAREN' or next_val.type == 'CBRACKET': self.line = iter([next_val] + [i for i in line]) return int(current.value.value) current.value.isValid(next_val.value) return_val = self.parse_expression(line) if not isinstance(return_val, int): raise mylang_errors.IncompatableTypes( "At line {}, near '{}': cannot {} variable of type '{}' to type '{}'" .format( current.value.line_number, current.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[next_val.type], type(self.variables[current.value.value]).__name__, type(return_val).__name__)) return operation_converters[next_val.type](int( current.value.value), return_val) if current.type == 'STRING': next_val = next(line, None) if not next_val or next_val.type == 'COMMA' or next_val.type == 'CPAREN' or next_val.type == 'CBRACKET': self.line = iter([next_val] + [i for i in self.line]) return current.value.value[1:-1] return_val = self.parse_expression(line) if not isinstance(return_val, str): raise mylang_errors.IncompatableTypes( "At line {}, near '{}': cannot {} variable of type '{}' to type '{}'" .format( current.value.line_number, current.value.value, { 'PLUS': 'concatinate', 'BAR': 'subtract', 'STAR': 'multiply', 'FORWARDSLASH': 'divide' }[next_val.type], type(current.value.value).__name__, type(return_val).__name__)) if next_val.type == "PLUS": return current.value.value[1:-1] + return_val raise mylang_errors.NotYetSupportedError("Operation not yet supported")