def run_stage(label, func): func(program, state) if verbose: divider(label) print(print_program(program))
def run(fn=None, src=None, exec_lines=-1, verbose=False, collect_stdout=False): """ Helper function for various uses of the glacia interpreter. Either fn or src must be specified to load a new program. If neither is present, the existing program in the database will be resumed. Arguments: fn (str): If present, the filename of the source code to load. src (str): If present, the source code to load. exec_lines (int): The number of lines to execute. -1 runs the program until the end. 0 loads the program but does not run it. verbose (bool): Whether to print extra information. collect_stdout (bool): Whether to collect and return the output of the program. """ if fn is not None and src is not None: raise Exception("fn and src cannot both be present.") # Read the file if needed. if src is None and fn is not None: with open(fn, 'rb') as f: src = f.read().decode('utf-8') # Compile and load the program if needed. if src is not None: state = CompilerState() if verbose: divider('Source code') print(src) src = preprocess(src) if verbose: divider('Preprocessed.') print(src) divider('Partially lexed (still with whitespace)') tokens = lex(src, preserve_whitespace=True) if verbose: print(print_tokens(tokens)) divider('Lexed') tokens = lex(src) if verbose: print(print_tokens(tokens,identifier_color='switch',line_width=60)) nodes = parse(tokens) if verbose: divider('Parsed') print(print_nodes(nodes).strip()) program = analyze(nodes) if verbose: divider('Analyzed') print(print_program(program)) def run_stage(label, func): func(program, state) if verbose: divider(label) print(print_program(program)) run_stage('Restructured', restructure) run_stage('Reduced', reduce) run_stage('Parameterized', parameterize) generated = generate(program) with close_after(Database()) as conn: load(conn, generated) if verbose: divider('Loaded DBIL') print(print_db(conn)) interpreter = Interpreter(conn) interpreter.start() # Run the program. if exec_lines != 0: if verbose: divider('Program output') collected = [] def collect_func(obj): collected.append(obj) stdout_func = None if collect_stdout: stdout_func = collect_func with close_after(Database()) as conn: interpreter = Interpreter(conn, stdout_func=stdout_func) if exec_lines < 0: interpreter.run() else: for i in range(exec_lines): if not interpreter.run_one_line(): break if collect_stdout: return collected