def __validate_command(value: (str, list)): command, params = value try: command = DataProvider.get_service_command(command) except KeyError: raise Validator.ValidationError(f"Wrong command name: `{command}`") if command.get_name() != Semantic.get_symbol( 'var') and command.get_attr_count() != len(params): raise Validator.ValidationError( f"Wrong params count: found {len(params)}" f" instead of {command.get_attr_count()}") if command.get_name() == Semantic.get_symbol('import'): Validator.__validate_import(params[0]) Validator.__import_module(params[0]) return param_types = command.get_param_types() for idx, param in enumerate(params): try: if ModuleManager.module_was_loaded('CORE'): if CommonValidator.looks_like_variable(param): raise ValueError param_types[idx](param) except ValueError: if ModuleManager.module_was_loaded('CORE'): if CommonValidator.looks_like_variable(param): CommonValidator.check_if_variable_exists(param) continue raise Validator.ValidationError( f"Wrong param type. Param #{idx + 1}: `{param}` " f"cannot be casted to {param_types[idx]}. ") except TypeError: new_params = params[idx + 1:] Validator.__validate_command((param, new_params)) break previous_command = DataProvider.peek_command_stack() if DataProvider.is_closing_command(command.get_name()) and \ not DataProvider.is_pair(previous_command, command.get_name()): raise Validator.ValidationError( f"Wrong command pair: [{previous_command}, {command.get_name()}]." ) try: command.get_validation_func()(params) except TypeError as ignored: # some commands may have no validation function pass
def __cut_out_comments(cls, text): lines = text.split('\n') for idx, line in enumerate(lines): try: comment = line[line.index(Semantic.get_symbol('comment')):] lines[idx] = line[:line.index(Semantic.get_symbol('comment'))] if comment: cls.comments.append((idx, comment)) except ValueError as ignored: pass return '\n'.join(lines)
def __run_command(self, command, params): command = DataProvider.get_service_command(command) if ModuleManager.module_was_loaded('CORE'): for idx, param in enumerate(params): try: CommonValidator.validate_name_variable(param) CommonValidator.check_if_variable_exists(param) variable = param[1:] params[idx] = DataProvider.get_variable_value(variable) except Exception: pass try: self.__validator.validate('command', (command.get_name(), params)) except (Validator.ValidationError, CommonValidator.ValidationError) as exception: raise Interpreter.RunTimeError( f'Command: `{command.get_name()}`. ' + str(exception)) param_types = command.get_param_types() for idx, param in enumerate(params): if inspect.isclass(param_types[idx]): params[idx] = param_types[idx](params[idx]) else: break try: self.__validator.validate('command', (command.get_name(), params)) except (Validator.ValidationError, CommonValidator.ValidationError) as exception: raise Interpreter.RunTimeError( f'Command: `{command.get_name()}`. ' + str(exception)) if command.get_name() == Semantic.get_symbol('var'): new_command, *new_params = params[2:] self.__run_command(new_command, new_params) params = params[:2] params.append(DataProvider.get_returned_value()) DataProvider.return_value(None) if command.get_name() == Semantic.get_symbol('import'): return try: command.get_exec_func()(*params) except CommonLogic.RunTimeError as exception: raise Interpreter.RunTimeError(f'Command: {command.get_name()}. ' f'{str(exception)}')
def check_if_variable_exists(value): value = value.lstrip('%') if value == Semantic.get_symbol('return_variable'): return if not value in DataProvider.get_variables().keys(): raise CommonValidator.ValidationError( f"Variable do not exist: `{value}`.")
def __validate_filename(self, value): if not path.isfile(value): raise Validator.ValidationError(f"File do not exist. " f"Check your filepath: `{value}`") file_extension = value.split('.')[-1] if file_extension != Semantic.get_extension(): raise Validator.ValidationError( f"File extension must be '.{Semantic.get_extension()}'.")
def __preprocess_line(self, line, w): # comments line = line.split('#')[0] parts = line.strip().split() # no action in this string if len(parts) == 0: w.write('\n') return command, *params = parts if ModuleManager.module_was_loaded('CORE'): try: CommonValidator.check_if_variable_exists(command) leading_spaces = self.__get_leading_spaces(line) line = " ".join([ ' ' * leading_spaces, Semantic.get_symbol('var'), line.lstrip() ]) parts = line.strip().split() command, *params = parts except Exception as ignored: pass try: self.__validator.validate('command', (command, params)) except Validator.ValidationError as exception: raise Preprocessor.ParseException(f"Command: `{command}`. " + str(exception)) if command == Semantic.get_symbol('var'): DataProvider.set_variable_value(params[0], None) elif DataProvider.is_opening_command(command): DataProvider.append_command_stack(command) elif DataProvider.is_closing_command(command): DataProvider.pop_command_stack() try: self.__command_to_func[command](line, w) except KeyError: w.write(line + '\n')
def validate_var(args): if len(args) < 3: # this exception should never be raised # if command was validated successfully raise CommonValidator.ValidationError( f'Var command must have at least 3 args, not {len(args)}.') CommonValidator.validate_name_variable('%' + args[0]) if args[1] != Semantic.get_symbol('var_separator'): raise CommonValidator.ValidationError( f'Wrong var separator: `{args[1]}`. ' f'You should use `{Semantic.get_symbol("var_separator")}`.')
def return_value(value): DataProvider.set_variable_value(Semantic.get_symbol('return_variable'), value)
def get_returned_value(): return DataProvider.get_variable_value( Semantic.get_symbol('return_variable'))
class TextStyler: comments = [] __just_replace = {'\n': '<br/>', ' ': ' '} __word_type = { 'command': sorted(ModuleManager.get_all_commands_names(), key=lambda x: len(x), reverse=True), 'operator': Semantic.get_operators() } __type_color = { 'command': 'blue', 'operator': 'red', 'comment': 'grey', 'regular_word': 'black' } @classmethod def plain_2_rich(cls, text): result = copy.deepcopy(text) result = cls.__cut_out_comments(result) for old in cls.__just_replace.keys(): new = cls.__just_replace[old] result = result.replace(old, new) for type in cls.__word_type: for word in cls.__word_type[type]: result = result.replace(word, cls.__get_colored_word(word)) return cls.__insert_comments(result) @classmethod def rich_2_plain(cls, text): result = copy.deepcopy(text) result = result.replace('<br />', '<br/>') for new in cls.__just_replace.keys(): old = cls.__just_replace[new] result = result.replace(old, new) x = cls.__clear_code(result) y = x[36:] + '\n' return y @classmethod def __cut_out_comments(cls, text): lines = text.split('\n') for idx, line in enumerate(lines): try: comment = line[line.index(Semantic.get_symbol('comment')):] lines[idx] = line[:line.index(Semantic.get_symbol('comment'))] if comment: cls.comments.append((idx, comment)) except ValueError as ignored: pass return '\n'.join(lines) @classmethod def __insert_comments(cls, text): lines = text.split('<br/>') for idx, comment in cls.comments: lines[idx] += (cls.__get_colored_word(comment, cls.__type_color['comment'])) cls.comments = [] return '<br/>'.join(lines) @classmethod def __get_colored_word(cls, word, color=None): if color: return f'<font color=\"{color}\">{word}</font>' word_type = "regular_word" for x in cls.__word_type.keys(): if word in cls.__word_type[x]: word_type = x color = cls.__type_color[word_type] return f'<font color=\"{color}\">{word}</font>' @classmethod def __clear_code(cls, rich): text = copy.deepcopy(rich) while True: try: text = text[:text.index('<')] + text[text.index('>') + 1:] except: break return text
def validate_name_variable(value): value = str(value) if not bool(re.match(Semantic.get_variable_name_pattern(), value)): raise CommonValidator.ValidationError( f"Wrong variable name: {value[1:]}.")