2 Copyright 2008, 2009 Free Software Foundation, Inc.
3 This file is part of GNU Radio
5 GNU Radio Companion is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 GNU Radio Companion is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 from .. base.FlowGraph import FlowGraph as _FlowGraph
22 from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph
23 from Block import Block
24 from Connection import Connection
27 _variable_matcher = re.compile('^(variable\w*)$')
28 _parameter_matcher = re.compile('^(parameter)$')
30 class FlowGraph(_FlowGraph, _GUIFlowGraph):
32 def __init__(self, **kwargs):
33 _FlowGraph.__init__(self, **kwargs)
34 _GUIFlowGraph.__init__(self)
35 self._eval_cache = dict()
37 def _eval(self, code, namespace, namespace_hash):
39 Evaluate the code with the given namespace.
40 @param code a string with python code
41 @param namespace a dict representing the namespace
42 @param namespace_hash a unique hash for the namespace
43 @return the resultant object
45 if not code: raise Exception, 'Cannot evaluate empty statement.'
46 my_hash = hash(code) ^ namespace_hash
47 #cache if does not exist
48 if not self._eval_cache.has_key(my_hash):
49 self._eval_cache[my_hash] = eval(code, namespace, namespace)
51 return self._eval_cache[my_hash]
53 def _get_io_signaturev(self, pad_key):
55 Get a list of io signatures for this flow graph.
56 The pad key determines the directionality of the io signature.
57 @param pad_key a string of pad_source or pad_sink
58 @return a list of dicts with: type, label, vlen, size
60 pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
61 sorted_pads = sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
64 'label': str(pad.get_param('label').get_evaluated()),
65 'type': str(pad.get_param('type').get_evaluated()),
66 'vlen': str(pad.get_param('vlen').get_evaluated()),
67 'size': pad.get_param('type').get_opt('size'),
68 } for pad in sorted_pads]
70 def get_input_signaturev(self):
72 Get the io signature for the input side of this flow graph.
73 @return a list of io signature structures
75 return self._get_io_signaturev('pad_source')
77 def get_output_signaturev(self):
79 Get the io signature for the output side of this flow graph.
80 @return a list of io signature structures
82 return self._get_io_signaturev('pad_sink')
84 def get_imports(self):
86 Get a set of all import statments in this flow graph namespace.
87 @return a set of import statements
89 imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
90 imports = sorted(set(imports))
93 def get_variables(self):
95 Get a list of all variables in this flow graph namespace.
96 Exclude paramterized variables.
97 @return a sorted list of variable blocks in order of dependency (indep -> dep)
99 variables = filter(lambda b: _variable_matcher.match(b.get_key()), self.get_enabled_blocks())
100 return expr_utils.sort_objects(variables, lambda v: v.get_id(), lambda v: v.get_var_make())
102 def get_parameters(self):
104 Get a list of all paramterized variables in this flow graph namespace.
105 @return a list of paramterized variables
107 parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks())
112 Flag the namespace to be renewed.
114 self._renew_eval_ns = True
115 _FlowGraph.rewrite(self)
117 def evaluate(self, expr):
119 Evaluate the expression.
120 @param expr the string expression
121 @throw Exception bad expression
122 @return the evaluated data
124 if self._renew_eval_ns:
125 self._renew_eval_ns = False
129 for imp in self.get_imports():
134 for parameter in self.get_parameters():
136 e = eval(parameter.get_param('value').to_code(), n, n)
137 np[parameter.get_id()] = e
139 n.update(np) #merge param namespace
141 for variable in self.get_variables():
143 e = eval(variable.get_param('value').to_code(), n, n)
144 n[variable.get_id()] = e
146 #make namespace public
148 self.n_hash = hash(str(n))
150 e = self._eval(expr, self.n, self.n_hash)