def run(self, op: dict): ''' Starts function block ''' self.require_one_argument( op, 'func operation requires function name argument') arg = op['args'][0] # check function already declared try: self.functions[self.current_namespace() + arg] self.raise_error( 'FunctionError', 'function "' + self.current_namespace() + arg + '" already declared', op) except KeyError: pass # declare function self.current_func = self.current_namespace() + arg self.functions[self.current_func] = [] # check for argument variable if len(op['args']) > 1: arg_var = op['args'][1].strip(')').strip('(') self.arg_should_be_variable(arg_var, op) self.functions[self.current_func].append( parser.parse(arg_var + ' = ^')[0])
def run_script(self, script_content: str, read_inputs=[], args=[], want_argv=False, stop_after_error=True) -> dict: ''' Runs a script and returns result ''' script_operations = parser.parse(script_content) prog = program.Program(is_test=self.is_test, args=args) prog.stop_after_error = stop_after_error prog.read_data = read_inputs prog.set_operations(script_operations) prog.start() out = {} out['vars'] = prog.variables out['output'] = prog.output out['runtime_error'] = prog.runtime_error out['mem'] = prog.mem try: out['exit_code'] = prog.exit_code except: out['exit_code'] = 0 del out['vars']['argc'] if not want_argv: del out['vars']['argv'] del out['vars']['pashmakinfo'] return out
def set_operations(self, operations: list): ''' Set operations list ''' # include stdlib before everything tmp = parser.parse( 'mem "@stdlib"; include ^; py "self.bootstrap_operations_count = len(self.operations)-2";' ) operations.insert(0, tmp[0]) operations.insert(1, tmp[1]) operations.insert(2, tmp[2]) # set operations on program object self.operations = operations
def run(self, op: dict): ''' Runs pashmak code from string ''' self.require_one_argument(op, 'eval operation requires argument') arg = op['args'][0] self.arg_should_be_variable_or_mem(arg, op) if arg == '^': code = self.get_mem() else: self.variable_required(arg[1:], op) code = self.get_var(arg[1:]) # run the code code_operations = parser.parse(code) for code_op in list(reversed(code_operations)): self.operations.insert(self.current_step+1, code_op) self.update_section_indexes(self.current_step+1)
def onMyToolbarButtonSyntax(self, s, label): erroresS.clear() self.output.setPlainText("") #print("Se activa el slot del syntax ",s ) dataT = self.input.toPlainText() #print("esto es data"+dataT) dataT = dataT.split("\r\n") for data in dataT: # if len(data)==0: # self.output.insertPlainText("No ha ingresado texto" + "\n") # else: # result = parser.parse(data) # print(result) result = parser.parse(data) self.output.insertPlainText("Errores sintácticos detectados: " + str(len(erroresS)) + "\n") for i in erroresS: self.output.insertPlainText(i)
def run(self, op: dict): ''' Includes another script file to program ''' self.require_one_argument(op, 'include operation requires argument') arg = op['args'][0] self.arg_should_be_variable_or_mem(arg, op) content = '' if arg == '^': path = self.get_mem() else: self.variable_required(arg[1:], op) path = self.get_var(arg[1:]) if not path: return if path[0] == '@': module_name = path[1:] try: if not module_name in self.included_modules: content = modules.modules[module_name] # add this module to imported modules self.included_modules.append(module_name) else: return except KeyError: self.raise_error('ModuleError', 'undefined module "' + module_name + '"', op) else: if path[0] != '/': path = os.path.dirname(os.path.abspath( self.main_filename)) + '/' + path try: content = open(path, 'r').read() except FileNotFoundError as ex: self.raise_error('FileError', str(ex), op) except PermissionError as ex: self.raise_error('FileError', str(ex), op) operations = parser.parse(content) self.exec_func(operations, False)
def start(self): ''' Start running the program ''' signal.signal(signal.SIGINT, self.signal_handler) is_in_func = False self.current_step = 0 # load the sections i = 0 while i < len(self.operations): current_op = self.set_operation_index(self.operations[i]) if current_op['command'] == 'section': if not is_in_func: arg = current_op['args'][0] self.sections[arg] = i + 1 self.operations[i] = parser.parse('pass')[0] elif current_op['command'] == 'func': is_in_func = True elif current_op['command'] == 'endfunc': is_in_func = False i += 1 self.current_step = 0 while self.current_step < len(self.operations): try: self.run(self.operations[self.current_step]) except Exception as ex: try: self.set_operation_index( self.operations[self.current_step]) except: break self.raise_error( 'RuntimeError', str(ex), self.set_operation_index( self.operations[self.current_step])) self.current_step += 1
def exec_func(self, func_body: list, with_state=True): ''' Gets a list from operations and runs them as function or included script ''' # create new state for this call if with_state: self.states.append({ 'entry_point': self.current_step, 'vars': dict(self.variables), }) # check function already called in this point if self.current_step in self.runed_functions and with_state: return # add this point to runed functions (for stop repeating call in loops) if with_state: self.runed_functions.append(self.current_step) # run function i = int(self.current_step) is_in_func = False for func_op in func_body: func_op_parsed = self.set_operation_index(func_op) if func_op_parsed['command'] == 'section' and not is_in_func: section_name = func_op_parsed['args'][0] self.sections[section_name] = i + 1 else: if func_op_parsed['command'] == 'func': is_in_func = True elif func_op_parsed['command'] == 'endfunc': is_in_func = False self.operations.insert(i + 1, func_op) self.update_section_indexes(i + 1) i += 1 if with_state: self.operations.insert(i + 1, parser.parse('popstate')[0]) self.update_section_indexes(i + 1)
import sys import logging from lexical import lexer from syntax import parser from codegen import CodeGenerator logging.basicConfig(level=logging.DEBUG, filename='parse.log', filemode='w', format='%(filename)10s:%(lineno)4d:%(message)s') log = logging.getLogger() if __name__ == '__main__': filename = sys.argv[1] s = open(filename).read() root = parser.parse(s, lexer=lexer, debug=log) cg = CodeGenerator(root) print(cg.generateProgram())
print('Pashmak Version: ' + version.version) print('Python Version: ', end='') print(sys.version.replace('\n', '')) sys.exit(0) if sys.argv[1] == '--version' or sys.argv[1] == '-v': print(version.version) sys.exit(0) filename = sys.argv[1] if sys.argv[1] == '-': script_content = '' for line in sys.stdin.readlines(): script_content += line elif not os.path.isfile(filename): print(sys.argv[0] + ': file "' + filename + '" not found') sys.exit(1) else: # read content of file and parse it with the parser script_f = open(filename, 'r') script_content = script_f.read() script_operations = parser.parse(script_content) # make pashmak program object prog = program.Program(args=sys.argv[1:]) prog.main_filename = filename prog.set_operations(script_operations) prog.start()
def run(self, op: dict): ''' Run once operation ''' op = self.set_operation_index(op) op_name = op['command'] if op_name == 'endfunc': self.run_endfunc(op) return if op_name == 'popstate': if self.states: self.states.pop() return # if a function is started, append current operation to the function body try: self.current_func self.functions[self.current_func].append(op) return except NameError: pass except KeyError: pass except AttributeError: pass # list of operations operations_dict = { 'set': self.run_set, 'free': self.run_free, 'copy': self.run_copy, 'read': self.run_read, 'return': self.run_return, 'func': self.run_func, 'required': self.run_required, 'typeof': self.run_typeof, 'system': self.run_system, 'include': self.run_include, 'goto': self.run_goto, 'gotoif': self.run_gotoif, 'fread': self.run_fread, 'fwrite': self.run_fwrite, 'chdir': self.run_chdir, 'cwd': self.run_cwd, 'isset': self.run_isset, 'out': self.run_out, 'try': self.run_try, 'endtry': self.run_endtry, 'eval': self.run_eval, 'arraypush': self.run_arraypush, 'arraypop': self.run_arraypop, 'python': self.run_python, 'namespace': self.run_namespace, 'endnamespace': self.run_endnamespace, 'use': self.run_use, 'pass': None, } # check op_name is a valid operation op_func = 0 try: op_func = operations_dict[op_name] except: pass # if op_name is a valid operation, run the function if op_func != 0: if op_func != None: op_func(op) return # check operation syntax is variable value setting if op['str'][0] == '$': parts = op['str'].strip().split('=', 1) varname = parts[0].strip() if len(parts) <= 1: self.set_var(varname[1:], None) return value = None if parts[1].strip()[0] == '^' and len(parts[1].strip()) > 1: cmd = parts[1].strip()[1:].strip() # insert cmd after current operation self.operations.insert(self.current_step + 1, parser.parse(cmd)[0]) self.update_section_indexes(self.current_step + 1) self.operations.insert(self.current_step + 2, parser.parse(varname + ' = ^')[0]) self.update_section_indexes(self.current_step + 2) return elif parts[1].strip() == '^': value = self.get_mem() else: value = self.eval(parts[1].strip()) self.set_var(varname[1:], value) return # check function exists try: func_body = self.functions[self.current_namespace() + op_name] except KeyError: func_body = None for used_namespace in self.used_namespaces: try: func_body = self.functions[used_namespace + '.' + op_name] except KeyError: pass if not func_body: try: func_body = self.functions[op_name] except KeyError: self.raise_error('SyntaxError', 'undefined operation "' + op_name + '"', op) return # run function try: # put argument in the mem if op['args_str'] != '': self.mem = self.eval(op['args_str']) else: self.mem = '' # execute function body self.exec_func(func_body) return except Exception as ex: self.raise_error('RuntimeError', str(ex), op)
def handle_input(user_input): tokens = tokenize(user_input) nodes = parse(tokens) expressions = evaluate(nodes) return expressions
from lexer.lexer import tokenize from syntax.parser import parse import sys if __name__ == '__main__': # file_code_path = sys.argv[1] file_code_path = 'tests/test.txt' token_list = tokenize(file_code_path) parse(token_list) for token in token_list: print(token)