예제 #1
0
def emit(g: Graph) -> Module:
    i = 0
    m = Module()
    variables: t.Dict[int, Symbol] = {}

    # TODO: with type
    # TODO: name
    original_args = [
        f"{node.name} string" for node in g.nodes if node.is_primitive
    ]
    with m.func("run", *original_args, return_="error"):
        for node in topological_sorted(g):
            if node.is_primitive:
                variables[node.uid] = m.symbol(node.name)
                continue

            args = []
            for dep in node.depends:
                args.append(variables[dep.uid])
            m.letN
            return_type = node.metadata.get("return_type", "")
            if return_type == "":
                [variables[node.uid]] = m.letN([f"v{i}"],
                                               m.symbol(node.name)(*args))
            elif return_type == "with-err":
                variables[node.uid], err = m.letN((f"v{i}", "err"),
                                                  m.symbol(node.name)(*args))
                with m.if_("err != nil"):
                    m.return_("err")
            elif return_type == "with-cleanup":
                variables[node.uid], cleanup = m.letN(
                    (f"v{i}", "cleanup"),
                    m.symbol(node.name)(*args))
                m.stmt("defer cleanup()")
            elif return_type == "with-cleanup-err":
                variables[node.uid], cleanup, err = m.letN(
                    (f"v{i}", "cleanup", "err"),
                    m.symbol(node.name)(*args))
                with m.if_("err != nil"):
                    m.return_("err")
                m.stmt("defer cleanup()")
            else:
                raise ValueError(f"unexpected return_type {return_type}")
            i += 1
        m.return_("nil")
    return m
예제 #2
0
def emit(g: Graph) -> Module:
    # TODO: name
    # TODO: import_
    i = 0
    m = Module()
    variables: t.Dict[int, Symbol] = {}

    with m.func("run", *_get_args(g), return_="error"):
        for node in topological_sorted(g):
            if node.is_primitive:
                variables[node.uid] = m.symbol(node.name)
                continue

            metadata = t.cast(Metadata, node.metadata)
            return_type = metadata.get("return_type", "")

            return_types = list(t.get_args(return_type) or [return_type])
            var_names = [
                f"v{i}",
                *[
                    getattr(typ, "name", typ.__name__)
                    for typ in return_types[1:]
                ],
            ]
            provider_callable = m.symbol(metadata.get("provider") or node.name)

            args = [variables[dep.uid] for dep in node.depends]
            variables[node.uid], *extra_vars = m.letN(var_names,
                                                      provider_callable(*args))
            if extra_vars:
                for sym, typ in sorted(
                        zip(extra_vars, return_types[1:]),
                        key=lambda pair: getattr(pair[1], "priority", 5),
                        reverse=True,
                ):
                    if hasattr(typ, "emit"):
                        typ.emit(m, sym)

            i += 1
        m.return_("nil")
    return m
예제 #3
0
def emit(g: Graph) -> Module:
    i = 0
    m = Module()
    variables: t.Dict[int, Symbol] = {}

    # TODO: with type
    # TODO: name
    root_args = [
        f"{node.name} string" for node in g.nodes if node.is_primitive
    ]
    with m.func("run", *root_args, return_="error"):
        for node in topological_sorted(g):
            if node.is_primitive:
                variables[node.uid] = m.symbol(node.name)
                continue

            metadata = t.cast(Metadata, node.metadata)
            return_type = metadata.get("return_type", "")

            return_types = list(t.get_args(return_type) or [return_type])
            var_names = [
                f"v{i}",
                *[
                    getattr(typ, "name", typ.__name__)
                    for typ in return_types[1:]
                ],
            ]
            provider_callable = m.symbol(metadata.get("provider") or node.name)

            args = [variables[dep.uid] for dep in node.depends]
            variables[node.uid], *extra_vars = m.letN(var_names,
                                                      provider_callable(*args))
            if extra_vars:
                for sym, typ in zip(extra_vars, return_types[1:]):
                    if hasattr(typ, "emit"):
                        typ.emit(m, sym)

            i += 1
        m.return_("nil")
    return m