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
20 from utils import expr_utils
21 from .. base.FlowGraph import FlowGraph as _FlowGraph
22 from Block import Block
23 from Connection import Connection
25 def _get_value_expr(variable_block):
27 Get the expression to evaluate from the value param.
28 Parameter blocks need to be evaluated so the stringify flag can be determined.
29 @param variable_block the variable or parameter block
30 @return the expression string
32 value_param = variable_block.get_param('value')
33 if variable_block.get_key() == 'parameter': value_param.evaluate()
34 return value_param.to_code()
36 class FlowGraph(_FlowGraph):
39 def _eval(self, code, namespace):
41 Evaluate the code with the given namespace.
42 @param code a string with python code
43 @param namespace a dict representing the namespace
44 @return the resultant object
46 my_hash = hash(code + str(namespace))
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_signature(self, pad_key):
55 Get an io signature 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 dict with: type, nports, vlen, size
60 pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
67 pad = pads[0] #take only the first, user should not have more than 1
70 'nports': str(pad.get_param('nports').evaluate()),
71 'type': str(pad.get_param('type').evaluate()),
72 'vlen': str(pad.get_param('vlen').evaluate()),
73 'size': pad.get_param('type').get_opt('size'),
76 def get_input_signature(self):
78 Get the io signature for the input side of this flow graph.
79 The io signature with be "0", "0" if no pad source is present.
80 @return a string tuple of type, num_ports, port_size
82 return self._get_io_signature('pad_source')
84 def get_output_signature(self):
86 Get the io signature for the output side of this flow graph.
87 The io signature with be "0", "0" if no pad sink is present.
88 @return a string tuple of type, num_ports, port_size
90 return self._get_io_signature('pad_sink')
92 def get_imports(self):
94 Get a set of all import statments in this flow graph namespace.
95 @return a set of import statements
97 imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
98 imports = sorted(set(imports))
101 def get_variables(self):
103 Get a list of all variables in this flow graph namespace.
104 Exclude paramterized variables.
105 @return a sorted list of variable blocks in order of dependency (indep -> dep)
107 variables = filter(lambda b: b.get_key() in (
108 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box'
109 ), self.get_enabled_blocks())
110 #map var id to variable block
111 id2var = dict([(var.get_id(), var) for var in variables])
112 #map var id to variable code
113 #variable code is a concatenation of all param code (without the id param)
114 id2expr = dict([(var.get_id(), var.get_param('value').get_value()) for var in variables])
115 #sort according to dependency
116 sorted_ids = expr_utils.sort_variables(id2expr)
117 #create list of sorted variable blocks
118 variables = [id2var[id] for id in sorted_ids]
121 def get_parameters(self):
123 Get a list of all paramterized variables in this flow graph namespace.
124 @return a list of paramterized variables
126 parameters = filter(lambda b: b.get_key() == 'parameter', self.get_enabled_blocks())
129 def evaluate(self, expr):
131 Evaluate the expression.
132 @param expr the string expression
133 @throw Exception bad expression
134 @return the evaluated data
136 if self.is_flagged():
141 for imp in self.get_imports():
146 for parameter in self.get_parameters():
148 e = self._eval(_get_value_expr(parameter), n)
149 np[parameter.get_id()] = e
151 n.update(np) #merge param namespace
153 for variable in self.get_variables():
155 e = self._eval(_get_value_expr(variable), n)
156 n[variable.get_id()] = e
158 #make namespace public
161 e = self._eval(expr, self.n)