Example #1
0
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)
Example #2
0
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
Example #3
0
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)