def run_yovec(source: str, root: str, no_elim: bool, no_reduce: bool, no_mangle: bool, ast: bool, cylon: bool) -> str: """Run Yovec.""" try: parser = Lark(YOVEC_EBNF, start='program') # type: ignore yovec = Node.from_tree(parser.parse(source)) except Exception as e: raise YovecError('Parse error: {}'.format(str(e))) try: transpiler = Transpiler(parser, root) # type: ignore env, yolol = transpiler.program(yovec) yolol, imported, exported = resolve_aliases(env, yolol) except YovecError as e: raise YovecError('Transpilation error: {}\n\n{}'.format(str(e), Context.format())) try: if not no_reduce: yolol = reduce_expressions(yolol) if not no_elim: yolol = eliminate_dead_code(yolol, exported) # type: ignore if not no_mangle: yolol = mangle_names(yolol, imported, exported) # type: ignore except YovecError as e: raise YovecError('Optimization error: {}\n\n{}'.format(str(e), Context.format())) if ast: return yolol.pretty() elif cylon: return yolol_to_cylon(yolol) else: return yolol_to_text(yolol)
def use_library(ident: str, parser, root: str) -> Sequence[Node]: """Use definitions from a library.""" logger.debug('using definitions from library - {}'.format(ident)) matches = list(Path(root).glob('**/{}.lib.yovec'.format(ident))) # type: ignore if len(matches) == 0: raise YovecError('library not found: {}'.format(ident)) if len(matches) > 1: raise YovecError('multiple files found for library {}: {}'.format(ident, [str(p) for p in matches])) try: with open(matches[0]) as f: text = f.read() except IOError as e: raise YovecError('unable to load library {}: {}'.format(ident, str(e))) try: program = Node.from_tree(parser.parse(text)) except Exception as e: raise YovecError('failed to parse library {}: {}'.format(ident, str(e))) statements = [line.children[0] for line in program.children] definitions = [] for statement in statements: if statement.kind == 'comment': continue elif statement.kind.startswith('def_'): # type: ignore definitions.append(statement) else: raise YovecError('invalid statement in library {}: {}'.format(ident, statement)) return definitions
def main(infile, outfile, ast=False): with open('grammar/yovec.ebnf') as f: grammar = f.read() parser = Lark(grammar, start='program') with open(infile) as f: raw_program = f.read() yovec_program = Node.from_tree(parser.parse(raw_program)) yolol_program = transpile_yovec(yovec_program) if ast: output = yolol_program.pretty() else: output = format_yolol(yolol_program) if outfile == '': print(output) else: with open(outfile, mode='w') as f: f.write(output)