def do_endloop(): DataProvider.set_peek_values_stack(DataProvider.peek_values_stack() - 1) if DataProvider.peek_values_stack() == 0: DataProvider.pop_command_stack() DataProvider.pop_values_stack() DataProvider.inc_current_line() # stepping over loop's goto
def preprocess_file(self, filename): try: self.__validator.validate('filename', filename) except Validator.ValidationError as exception: raise Preprocessor.ParseException(str(exception)) o_filename = filename.replace(f'.{Semantic.get_extension()}', f'.o.{Semantic.get_extension()}') with open(filename) as r: lines = [line.rstrip() for line in r] w = open(o_filename, 'w') for idx, line in enumerate(lines): try: self.__preprocess_line(line, w) except Preprocessor.ParseException as exception: raise Preprocessor.ParseException(f"Line: {idx + 1}. " + str(exception)) w.close() try: self.__validator.validate('command_stack', DataProvider.get_command_stack()) except Validator.ValidationError as exception: raise Preprocessor.ParseException(str(exception)) DataProvider.clear_command_stack() DataProvider.clear_variables() return o_filename
def validate(self, type: str, value): if not type in self.__entity_to_func.keys(): raise Validator.InvalidObjectTypeException( f"Wrong validation type: `{type}`.") try: self.__entity_to_func[type](value) except KeyError: DataProvider.get_service_command(type).get_validation_func()(value) except CommonValidator.ValidationError as exception: raise Validator.ValidationError(str(exception))
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 __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 get_element_from_html(filename, traverse_tags, cmd, cmd_value): with open(filename, 'r') as file: content = file.read() soup = BeautifulSoup(content, 'lxml') tags = traverse_tags.split('@') if tags[0] == "": tags = tags[1:] current = soup for tag in tags: tag_name, *tag_cnts = tag.split('!') tag_cnts.append(1) tag_cnt = int(tag_cnts[0]) next_child = None children = [e for e in current.children if e.name is not None] for child in children: if child.name == tag_name: tag_cnt -= 1 if tag_cnt == 0: next_child = child break if not next_child: raise CommonLogic.RunTimeError() current = next_child if cmd == 'attr': try: # DataProvider.return_value("http:" + current[cmd_value]) DataProvider.return_value('https:' + current[cmd_value]) except: raise CommonLogic.RunTimeError( f'Wrong attribute value `{cmd_value}`') elif cmd == 'field': parts = current.text.split() parts = [part.strip() for part in parts] DataProvider.return_value(" ".join(parts)) else: raise CommonLogic.RunTimeError(f'Wrong attribute name `{cmd}`')
def parse_file(self, filename): filename = copy.deepcopy(filename) ModuleManager.download_default_modules() Logger.log("Compiling...") try: filename = self.__preproccessor.preprocess_file(filename) except Preprocessor.ParseException as exception: raise Interpreter.CompilationError("Compilation error: " + str(exception)) Logger.log("Compilation succeed. Running...") with open(filename) as f: lines = [line.rstrip() for line in f] while True: idx = DataProvider.get_current_line() try: line = lines[idx] except IndexError: break if len(line) == 0: DataProvider.inc_current_line() continue try: self.__parse_line(line) except Interpreter.RunTimeError as exception: raise Interpreter.RunTimeError( f"Runtime error. Line: {idx + 1}. " + str(exception)) DataProvider.inc_current_line() Logger.log("Program finished.")
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 do_inc(value): DataProvider.return_value(value + 1)
def format_length(string, length, symbol): res = symbol * (length - len(string)) + string DataProvider.return_value(res)
def get_month_name(month): x = calendar.month_name[month] DataProvider.return_value(x)
def days_count_by_month(year, month): days = [ 31, 28 + (year % 4 == 0), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] DataProvider.return_value(days[month - 1])
def do_replace(s, t1, t2): DataProvider.return_value(s.replace(t1, t2))
def get_variable(name: str): name = name.lstrip('%') return DataProvider.get_variable_value(name)
def do_goto(label): DataProvider.set_current_line(DataProvider.get_label_line(label))
def do_const(value): DataProvider.return_value(value)
def do_loop(cnt): DataProvider.append_values_stack(cnt) DataProvider.append_command_stack('loop')
def set_variable(name: str, value): name = name.lstrip('%') DataProvider.set_variable_value(name, value)
def add_command(name, function, attr_types, closing_command, validation): DataProvider.add_service_command( Command(name, function, attr_types, validation, closing_command))
def clear_variables(): DataProvider.clear_variables()
def validate_goto(args): if not args[0] in DataProvider.get_labels(): raise CommonValidator.ValidationError( f"Wrong label name: `{args[0]}`.")
def do_label(label): DataProvider.set_label_line(label, DataProvider.get_current_line())
def __reboot_core(cls): DataProvider.reboot() ModuleManager.reboot()
def do_concat(s, t): DataProvider.return_value(s + t)
def load_page(url): session = requests.Session() response = session.get(url) content = response.text DataProvider.return_value(content)
def validate_name_command(value): if not DataProvider.is_command(value): raise CommonValidator.ValidationError()