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
def __init__(self, obj_type, args, graph, annotations=None): HeavyLangObject.__init__(self, "biquad", args, graph, num_inlets=6, num_outlets=1, annotations=annotations)
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)
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)
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)
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)
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)
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)
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))
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
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"]))
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()}
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
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)
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
def __init__(self, obj_type, args, graph, annotations=None): HeavyLangObject.__init__(self, "send", args, graph, annotations=annotations)