Example #1
0
    def __init__(self,
                 obj_type,
                 args=None,
                 graph=None,
                 num_inlets=-1,
                 num_outlets=-1,
                 annotations=None):
        # allow the number of inlets and outlets to be overridden
        num_inlets = len(HeavyIrObject.__HEAVY_OBJS_IR_DICT[obj_type]["inlets"]) \
        if num_inlets < 0 else num_inlets

        num_outlets = len(HeavyIrObject.__HEAVY_OBJS_IR_DICT[obj_type]["outlets"]) \
        if num_outlets < 0 else num_outlets

        HeavyLangObject.__init__(self, obj_type, args, graph, num_inlets,
                                 num_outlets, annotations)

        # resolve arguments and fill in missing defaults for HeavyIR objects
        self.__resolve_default_ir_args()

        # the list of signal buffers at the inlets and outlets
        # these are filled in by HeavyGraph.assign_signal_buffers()
        self.inlet_buffers = [("zero", 0)] * self.num_inlets
        self.outlet_buffers = [("zero", 0)] * self.num_outlets

        # True if this object has already been ordered in the signal chain
        self.__is_ordered = False
Example #2
0
 def __init__(self, obj_type, args, graph, annotations=None):
     HeavyLangObject.__init__(self,
                              "biquad",
                              args,
                              graph,
                              num_inlets=6,
                              num_outlets=1,
                              annotations=annotations)
Example #3
0
 def __init__(self, obj_type, args, graph, annotations=None):
     assert obj_type == "delay"
     HeavyLangObject.__init__(self,
                              "delay",
                              args,
                              graph,
                              num_inlets=2,
                              num_outlets=1,
                              annotations=annotations)
Example #4
0
 def __init__(self, obj_type, args, graph, annotations=None):
     assert obj_type == "slice"
     HeavyLangObject.__init__(self,
                              obj_type,
                              args,
                              graph,
                              num_inlets=3,
                              num_outlets=2,
                              annotations=annotations)
Example #5
0
 def __init__(self, obj_type, args, graph, annotations=None):
     assert obj_type == "print"
     HeavyLangObject.__init__(self,
                              obj_type,
                              args,
                              graph,
                              num_inlets=1,
                              num_outlets=0,
                              annotations=annotations)
Example #6
0
 def __init__(self, obj_type, args, graph, annotations=None):
     assert HLangUnop.handles_type(obj_type)
     HeavyLangObject.__init__(self,
                              obj_type,
                              args,
                              graph,
                              num_inlets=1,
                              num_outlets=1,
                              annotations=annotations)
Example #7
0
 def __init__(self, obj_type, args, graph, annotations=None):
     HeavyLangObject.__init__(
         self,
         obj_type,
         args,
         graph,
         num_inlets=0,
         num_outlets=len(args[HeavyLangObject._HEAVY_LANG_DICT[obj_type]
                              ["args"][0]["name"]]),
         annotations=annotations)
Example #8
0
 def __init__(self, obj_type, args, graph, annotations=None):
     # get the number of outlets that this object has
     num_outlets = len(args[HeavyLangObject._HEAVY_LANG_DICT[obj_type]
                            ["args"][0]["name"]])
     HeavyLangObject.__init__(self,
                              obj_type,
                              args,
                              graph,
                              num_inlets=1,
                              num_outlets=num_outlets,
                              annotations=annotations)
Example #9
0
    def reduce(self):
        if self.has_inlet_connection_format("c"):
            ir_args = dict(self.args)
            ir_args["hash"] = "0x{0:X}".format(
                HeavyLangObject.get_hash(ir_args["name"]))
            x = HIrSend("__send", ir_args, annotations=self.annotations)
            return ({x}, self.get_connection_move_list(x))

        elif self.has_inlet_connection_format("f"):
            # this case should be handled already in HeavyGraph.remap_send_receive()
            # clean up just in case
            return (set(), [])

        elif self.has_inlet_connection_format("_"):
            self.add_warning(
                "send~ object doesn't have any inputs, this one is being removed."
            )
            return (set(), [])

        elif self.has_inlet_connection_format("m"):
            self.add_error(
                "Inlet can support either control or signal connections, "
                "but not both at the same time.")

        else:
            fmt = self._get_connection_format(self.inlet_connections)
            self.add_error("Unknown inlet configuration: {0}".format(fmt))
Example #10
0
 def get_notices(self):
     notices = HeavyLangObject.get_notices(self)
     for o in self.objs.values():
         n = o.get_notices()
         notices["warnings"].extend(n["warnings"])
         notices["errors"].extend(n["errors"])
     return notices
Example #11
0
    def __init__(self, obj_type, args, graph, annotations=None):
        assert obj_type == "table"
        HeavyLangObject.__init__(self,
                                 obj_type,
                                 args,
                                 graph,
                                 annotations=annotations)

        # the values argument overrides the size argument
        if len(self.args.get("values", [])) > 0:
            self.args["size"] = len(self.args["values"])

        if self.args["extern"]:
            # externed tables must contain only alphanumeric characters or underscores,
            # so that the names can be easily and transparently turned into code
            if re.search("\W", args["name"]):
                self.add_error(
                    "Table names may only contain alphanumeric characters or underscore: '{0}'"
                    .format(args["name"]))
Example #12
0
 def get_ir_receiver_dict(self):
     # NOTE(mhroth): this code assumes that v is always an array of length 1,
     # as the grouping of control receivers should have grouped all same-named
     # receivers into one logical receiver.
     # NOTE(mhroth): a code-compatible name is only necessary for externed receivers
     return {(("_"+k) if re.match("\d",k) else k): {
         "display": k,
         "hash": "0x{0:X}".format(HeavyLangObject.get_hash(k)),
         "extern": v[0].args["extern"],
         "attributes": v[0].args["attributes"],
         "ids": [v[0].id]
     } for k,v in self.local_vars.get_registered_objects_for_type("__receive").iteritems()}
Example #13
0
    def get_ir_table_dict(self):
        """ Returns a dictionary of all publicly visible tables at the root graph
            and their ids.
        """
        assert self.is_root_graph(), "This function should only be called from the root graph."
        d = self.local_vars.get_registered_objects_for_type("__table")
        # update(), because tables can be registered either as Heavy tables
        # or HeavyIr __tables. We need to be able to handle them both.
        d.update(self.local_vars.get_registered_objects_for_type("table"))

        e = {}
        for k, v in d.iteritems():
            # escape table key to be used as the value for code stubs
            key = ("_"+k) if re.match("\d", k) else k
            if key not in e:
                e[key] = {
                    "id": v[0].id,
                    "display": k,
                    "hash": "0x{0:X}".format(HeavyLangObject.get_hash(k)),
                    "extern": v[0].args["extern"]
                }
        return e
Example #14
0
 def __resolve_default_ir_args(self):
     """ Resolves missing default arguments. Also checks to make sure that all
         required arguments are present.
     """
     if self.type in HeavyIrObject.__HEAVY_OBJS_IR_DICT:
         for arg in self.__obj_desc.get("args", []):
             if arg["name"] not in self.args:
                 # if a defined argument is not in the argument dictionary
                 if not arg["required"]:
                     # if the argument is not required, use the default
                     self.args[arg["name"]] = arg["default"]
                 else:
                     self.add_error(
                         "Required argument \"{0}\" not present for object {1}."
                         .format(arg["name"], self))
             else:
                 # enforce argument types.
                 # if the default argument is null, don't worry about about the arg
                 if arg["default"] is not None:
                     self.args[
                         arg["name"]] = HeavyLangObject.force_arg_type(
                             self.args[arg["name"]], arg["value_type"],
                             self.graph)
Example #15
0
    def graph_from_object(clazz, json_heavy, graph=None, graph_args=None, hv_file=None, path_stack=None, xname=None):
        """ Parse a graph object.

            @param graph  The parent graph.
            @param graph_args  The resolved arguments to this graph, in the form of a dictionary.
            @param hv_file  The Heavy file where this graph can be found.
        """
        # resolve default graph arguments
        graph_args = graph_args or {}
        for a in json_heavy["args"]:
            if a["name"] not in graph_args:
                if a["required"]:
                    raise HeavyException("Required argument \"{0}\" not present.".format(a["name"]))
                else:
                    graph_args[a["name"]] = a["default"]
            else:
                # just to be safe, ensure that the argument type is correct
                graph_args[a["name"]] = HeavyLangObject.force_arg_type(
                    graph_args[a["name"]],
                    a["value_type"],
                    graph=graph)

        # create a new graph
        subpatch_name = json_heavy.get("annotations",{}).get("name", xname)
        g = HeavyGraph(graph, graph_args, file=hv_file, xname=subpatch_name)

        # add the import paths to the global vars
        g.local_vars.add_import_paths(json_heavy.get("imports",[]))
        # add the file's relative directory to global vars
        g.local_vars.add_import_paths([os.path.dirname(hv_file)])

        # instantiate all objects
        try:
            for obj_id, o in json_heavy["objects"].iteritems():
                if o["type"] == "comment":
                    continue # first and foremost, ignore comment objects

                elif o["type"] == "graph":
                    # inline HeavyGraph objects (i.e. subgraphs)
                    # require a different set of initialisation arguments
                    x = HeavyParser.graph_from_object(o, g, g.args, hv_file, path_stack, xname)

                else:
                    # resolve the arguments dictionary based on the graph args
                    args = g.resolve_arguments(o["args"])

                    # before anything, search for an abstraction
                    # in case we want to override default functionality
                    # However, if we are in an abstraction that has the same
                    # name as the type that we are looking for, don't recurse!
                    abs_path = g.find_path_for_abstraction(o["type"])
                    if abs_path is not None and abs_path not in path_stack:
                        x = HeavyParser.graph_from_file(
                            hv_file=abs_path,
                            graph=g,
                            graph_args=args,
                            path_stack=path_stack)

                    # if we know how to handle this object type natively
                    # either as a custom type or as a generic IR object
                    elif HeavyParser.get_class_for_type(o["type"]) is not None:
                        obj_clazz = HeavyParser.get_class_for_type(o["type"])
                        x = obj_clazz(o["type"], args, g, o.get("annotations", {}))

                    # handle generic IR objects
                    elif HeavyIrObject.is_ir(o["type"]):
                        x = HeavyIrObject(o["type"], args, g, annotations=o.get("annotations", {}))

                    # an object definition can't be found
                    else:
                        g.add_error("Object type \"{0}\" cannot be found.".format(o["type"]))
                        # note that add_error() raises an exception. So really, there is no continue.
                        continue

                # add the new object to the graph's object dictionary
                g.add_object(x, obj_id)

            # parse all of the connections
            for c in json_heavy["connections"]:
                g.connect_objects(Connection(
                    g.objs[c["from"]["id"]],
                    c["from"]["outlet"],
                    g.objs[c["to"]["id"]],
                    c["to"]["inlet"],
                    c["type"]))

        except HeavyException as e:
            if g.is_root_graph():
                # add the notification dictionary at the top level
                e.notes = g.get_notices()
                e.notes["has_error"] = True
                e.notes["exception"] = e
            raise e

        if (g.graph is None) or (g.graph.file != g.file):
            # remove this graph from the stack when finished.
            # Subpatches should not remove themselves.
            path_stack.remove(g.file)

        return g
Example #16
0
 def __init__(self, obj_type, args, graph, annotations=None):
     HeavyLangObject.__init__(self,
                              "send",
                              args,
                              graph,
                              annotations=annotations)