Esempio n. 1
0
def reduce_expressions(program: Node) -> Node:
    """Reduce expressions in a YOLOL program."""
    assert program.kind == 'program'
    logger.debug('reducing expressions')
    clone = program.clone()
    while _propagate_constants(clone) or _fold_constants(clone):
        pass
    return clone
Esempio n. 2
0
def mangle_names(program: Node, imported: Sequence[str],
                 exported: Sequence[str]) -> Node:
    """Mangle names in a YOLOL program."""
    assert program.kind == 'program'
    logger.debug('mangling names')
    clone = program.clone()
    pool = Pool([*imported, *exported])
    variables = clone.find(lambda node: node.kind == 'variable')
    for var in variables:
        var.value = pool.replace(var.value)  # type: ignore
    return clone
Esempio n. 3
0
def resolve_aliases(env: Env,
                    program: Node) -> Tuple[Node, Set[str], Set[str]]:
    """Resolve aliases to their targets in a YOLOL program."""
    assert program.kind == 'program'
    logger.debug('resolving aliases')

    clone = program.clone()
    imported = set()
    exported = set()

    for alias, target in env.imports.items():
        variables = clone.find(
            lambda node: node.kind == 'variable' and node.value == alias)
        for var in variables:
            var.value = target
            imported.add(target)

    for alias, target in env.exports.items():
        var, index = env.var(alias)

        if type(var) == Number:
            num_prefix = '{}{}'.format(Number.PREFIX, index)
            num_variables = clone.find(lambda node: node.kind == 'variable' and
                                       node.value.startswith(num_prefix))
            for var in num_variables:
                var.value = var.value.replace(num_prefix,
                                              target)  # type: ignore
                exported.add(var.value)

        elif type(var) == Vector:
            vec_prefix = '{}{}'.format(Vector.PREFIX, index)
            vec_variables = clone.find(lambda node: node.kind == 'variable' and
                                       node.value.startswith(vec_prefix))
            for var in vec_variables:
                var.value = var.value.replace(vec_prefix,
                                              target)  # type: ignore
                exported.add(var.value)

        elif type(var) == Matrix:
            mat_prefix = '{}{}'.format(Matrix.PREFIX, index)
            mat_variables = clone.find(lambda node: node.kind == 'variable' and
                                       node.value.startswith(mat_prefix))
            for var in mat_variables:
                var.value = var.value.replace(mat_prefix,
                                              target)  # type: ignore
                exported.add(var.value)

        else:
            raise AssertionError('unexpected variable type: {}'.format(
                type(var)))

    return clone, imported, exported
Esempio n. 4
0
def _remove_dead(program: Node, alive: Set[str]) -> Node:
    """Remove dead assignments."""
    assert program.kind == 'program'
    logger.debug('removing dead assignments')
    clone = program.clone()
    assignments = clone.find(lambda node: node.kind == 'assignment')
    for asn in assignments:
        if asn.children[0].value not in alive:
            assert asn.parent is not None
            asn.parent.remove_child(asn)  # type: ignore
    lines = clone.find(lambda node: node.kind == 'line')
    for line in lines:
        if len(line.children) == 0:
            assert line.parent is not None
            line.parent.remove_child(line)  # type: ignore
    return clone