def execute(cls, eargs): #@todo one time warning if infinite loop detected for_code_index = Code_line.get_jump(eargs.code_line, ForCommand._FOR) _, line_tokens, _ = Code_line.split(eargs.code_lines[for_code_index]) variable_name, from_value, to_value, step_value = ForCommand.evaluate_for_tokens(line_tokens) value = eargs.context.get_variable(variable_name) value = value + step_value eargs.context.set_variable(variable_name, value) if from_value < to_value: if value < to_value: eargs.context.jump_to_code(for_code_index + 1) else: if value > to_value: eargs.context.jump_to_code(for_code_index + 1)
def parse(pargs): #@ error when missing begin and end parenthesis # mark all names as keywords, we do value replacement on execute _, line_tokens, _ = Code_line.split(pargs.code_line) for i in range(0, len(line_tokens)): if line_tokens.is_name(i): line_tokens.mark_as_keyword(i)
def create_code_line(line_number, var_name): tokens = Tokens("{}".format(SetretCommand._keyword)) tokens.insert_name(1, var_name) tokens.mark_as_keyword(0) tokens.mark_as_keyword(1) code_line = Code_line.create(line_number, tokens, SetretCommand) return code_line
def filter(code_lines, filters): ret = [] for i in range(0, len(code_lines)): line_number, line_tokens, _ = Code_line.split(code_lines[i]) if line_tokens.is_name(0) and line_tokens.is_value_no_case( 0, filters): ret.append((line_number, line_tokens)) return ret
def parse(cls, pargs): #@todo error when no correct order if, elif..., else, endif #@todo error when no endif if_commands = cls.search_for_if_commands(pargs.code_lines, pargs.code_index) end_if_label_name = pargs.code_labels.get_label_name(IfCommand._END_IF) Code_line.add_label(pargs.code_lines[if_commands[-1]], end_if_label_name) #add jumps to next elif, else commands marked with their labels for i in range(0, len(if_commands) - 1): next_if_label_name = pargs.code_labels.get_label_name( IfCommand._ELSE) Code_line.add_label(pargs.code_lines[if_commands[i + 1]], next_if_label_name) Code_line.add_jump(pargs.code_lines[if_commands[i]], IfCommand._ELSE, next_if_label_name) # inserting jump command before each elif or else for i in range(1, len(if_commands) - 1): line_number = Code_line.get_line_number( pargs.code_lines[if_commands[i]]) jump_code_line = JumpCommand.create_code_line( line_number, end_if_label_name) pargs.code_lines_insertion.insert_before(line_number, jump_code_line)
def move(code_lines, first_line_number, last_line_number): ret = [] from_index = 0 to_index = len(code_lines) while from_index < to_index: line_number, _, _ = Code_line.split(code_lines[from_index]) if first_line_number <= line_number and line_number <= last_line_number: ret.append(code_lines[from_index]) del code_lines[from_index] to_index -= 1 else: from_index += 1 return ret
def evaluate_function_calls(cls, pargs): line_tokens = Code_line.get_line_tokens(pargs.code_line) line_number = Code_line.get_line_number(pargs.code_line) cls.mark_functions_as_keywords(line_tokens) next_rightest_function = cls.rightest_function(line_tokens, pargs.code) var_index = 0 while next_rightest_function: # using number as set ret variable name to prevent collision with other 'normal' variables #@todo if number is used as variable name in code, log error var_name = "{}".format(var_index) i, j, type = next_rightest_function function_tokens = line_tokens.pop_tokens(i - 1, j + 1) func_name = function_tokens.value(0) line_tokens.insert_name(i, var_name) if type == cls._FISD_FUNCTION: call_code_line = CallCommand.create_code_line( line_number, function_tokens) elif type == cls._FISD_COMMAND: call_code_line = Commands.find_command( func_name).create_code_line(line_number, function_tokens) next_rightest_function = cls.rightest_function( line_tokens, pargs.code) call_ret_code_line = SetretCommand.create_code_line( line_number, var_name) pargs.code_lines_insertion.insert_before(line_number, call_code_line) pargs.code_lines_insertion.insert_before(line_number, call_ret_code_line) var_index += 1
def search_for_loop_end(cls, code_lines, code_index): nested_counter = 0 for i in range(code_index + 1, len(code_lines)): _, line_tokens, _ = Code_line.split(code_lines[i]) if line_tokens.is_value_no_case(0, cls._FOR): nested_counter += 1 if line_tokens.is_value_no_case(0, cls._NEXT): if nested_counter == 0: return i else: nested_counter -= 1 return None #hen no next found!
def parse(cls, pargs): _, line_tokens, _ = Code_line.split(pargs.code_line) line_tokens.mark_as_keyword(1) #@todo error if wrong arguments #detecting loop end and set jump code index for next and for commands into their code_lines for_code_index = pargs.code_index next_code_index = cls.search_for_loop_end(pargs.code_lines, pargs.code_index) if not next_code_index: #@todo error no loop ending #@todo error when variable name is not the same for for and next #@todo warning if no variable name behind next pass else: for_label_name = pargs.code_labels.get_label_name(cls._FOR) next_label_name = pargs.code_labels.get_label_name(cls._NEXT) Code_line.add_label(pargs.code_lines[for_code_index], for_label_name) Code_line.add_label(pargs.code_lines[next_code_index], next_label_name) Code_line.add_jump(pargs.code_lines[for_code_index], cls._NEXT, next_label_name) Code_line.add_jump(pargs.code_lines[next_code_index], cls._FOR, for_label_name)
def restore_execution_context(self, execution_stack_index, context): execution_context = self._stack[execution_stack_index] if execution_stack_index + 1 < len(self._stack): context.execute_code(execution_context[Execution_stack._CODE_NAME], execution_stack_index + 1) else: # in case of last execution context, we search for restoration point code line # so code will start from that point code_lines = self._code.get_code_lines( execution_context[Execution_stack._CODE_NAME]) while execution_context[Execution_stack._CODE_INDEX] < len( code_lines): cmd_class = Code_line.get_command_class( code_lines[execution_context[Execution_stack._CODE_INDEX]]) if cmd_class._keyword == Fisd_restore_context_command._keyword: break execution_context[Execution_stack._CODE_INDEX] += 1 # after restoring always starts from next code line execution_context[Execution_stack._CODE_INDEX] += 1 return execution_context
def search_for_if_commands(cls, code_lines, code_index): ''' Returns code indicies for all if conditional commands (if, elif, else, endif)''' ret = [] nested_counter = 0 ret.append(code_index) for i in range(code_index + 1, len(code_lines)): _, line_tokens, _ = Code_line.split(code_lines[i]) if line_tokens.is_value_no_case(0, cls._IF): nested_counter += 1 if line_tokens.is_value_no_case(0, cls._END_IF): if nested_counter == 0: ret.append(i) return ret else: nested_counter -= 1 if nested_counter == 0: if line_tokens.is_value_no_case(0, [cls._ELSE, cls._ELIF]): ret.append(i) return None #When no endif found!
def parse(cls, pargs): line_tokens = Code_line.get_line_tokens(pargs.code_line) line_tokens.mark_as_keyword(1)
def parse(cls, pargs): _, line_tokens, _ = Code_line.split(pargs.code_line) line_tokens.mark_as_keyword(1)
def execute(cls, eargs): variable_name, from_value, to_value, step_value = cls.evaluate_for_tokens(eargs.raw_args) eargs.context.set_variable(variable_name, from_value) next_code_index = Code_line.get_jump(eargs.code_line, cls._NEXT)
def line_tokens(self): return Code_line.get_line_tokens(self.code_line)
def execute(eargs): if not eargs.raw_args.evaluate_tokens(0, len(eargs.raw_args) - 1): eargs.context.jump_to_code( Code_line.get_jump(eargs.code_line, IfCommand._ELSE))
def create_code_line(line_number, jump_label_name): tokens = Tokens(JumpCommand._keyword) tokens.mark_as_keyword(0) code_line = Code_line.create(line_number, tokens, JumpCommand) Code_line.add_jump(code_line, JumpCommand._keyword, jump_label_name) return code_line
def execute(params): params.context.jump_to_code(Code_line.get_jump(params.code_line, JumpCommand._keyword))
def create_code_line(line_number, tokens): tokens.insert_name(0, CallCommand._keyword) tokens.mark_as_keyword(0) code_line = Code_line.create(line_number, tokens, CallCommand) return code_line
def create_code_line(cls, line_number, tokens): assert tokens.value(0).lower() == cls._keyword, "" code_line = Code_line.create(line_number, tokens, cls) return code_line
def current_line_number(self): code_lines = self._code.get_code_lines(self.current_code_name) return Code_line.get_line_number(code_lines[self.current_code_index])
def line_number(self): return Code_line.get_line_number(self.code_line)