summaryrefslogtreecommitdiff
path: root/grc/src/platforms/python/FlowGraph.py
diff options
context:
space:
mode:
Diffstat (limited to 'grc/src/platforms/python/FlowGraph.py')
-rw-r--r--grc/src/platforms/python/FlowGraph.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/grc/src/platforms/python/FlowGraph.py b/grc/src/platforms/python/FlowGraph.py
new file mode 100644
index 000000000..6c9b7f642
--- /dev/null
+++ b/grc/src/platforms/python/FlowGraph.py
@@ -0,0 +1,152 @@
+"""
+Copyright 2008 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
+
+from utils import expr_utils
+from .. base.FlowGraph import FlowGraph as _FlowGraph
+from Block import Block
+from Connection import Connection
+
+def get_variable_code(variable):
+ """
+ Get the code representation for a variable.
+ Normally this is the value parameter.
+ For the variable chooser, use the index and choices.
+ Avoid using the to_code method of the variables,
+ as this forces evaluation before the variables are evaluated.
+ @param variable the variable block
+ @return the code string
+ """
+ if variable.get_key() == 'variable_chooser':
+ choices = variable.get_param('choices').get_value()
+ value_index = variable.get_param('value_index').get_value()
+ return "(%s)[%s]"%(choices, value_index)
+ return variable.get_param('value').get_value()
+
+class FlowGraph(_FlowGraph):
+
+ def _get_io_signature(self, pad_key):
+ """
+ Get an io signature for this flow graph.
+ The pad key determines the directionality of the io signature.
+ @param pad_key a string of pad_source or pad_sink
+ @return a dict with: type, nports, vlen, size
+ """
+ pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
+ if not pads: return {
+ 'nports': '0',
+ 'type': '',
+ 'vlen': '0',
+ 'size': '0',
+ }
+ pad = pads[0] #take only the first, user should not have more than 1
+ #load io signature
+ return {
+ 'nports': str(pad.get_param('nports').evaluate()),
+ 'type': str(pad.get_param('type').evaluate()),
+ 'vlen': str(pad.get_param('vlen').evaluate()),
+ 'size': pad.get_param('type').get_opt('size'),
+ }
+
+ def get_input_signature(self):
+ """
+ Get the io signature for the input side of this flow graph.
+ The io signature with be "0", "0" if no pad source is present.
+ @return a string tuple of type, num_ports, port_size
+ """
+ return self._get_io_signature('pad_source')
+
+ def get_output_signature(self):
+ """
+ Get the io signature for the output side of this flow graph.
+ The io signature with be "0", "0" if no pad sink is present.
+ @return a string tuple of type, num_ports, port_size
+ """
+ return self._get_io_signature('pad_sink')
+
+ def get_imports(self):
+ """
+ Get a set of all import statments in this flow graph namespace.
+ @return a set of import statements
+ """
+ imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
+ imports = sorted(set(imports))
+ return imports
+
+ def get_variables(self):
+ """
+ Get a list of all variables in this flow graph namespace.
+ Exclude paramterized variables.
+ @return a sorted list of variable blocks in order of dependency (indep -> dep)
+ """
+ variables = filter(lambda b: b.get_key() in (
+ 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box'
+ ), self.get_enabled_blocks())
+ #map var id to variable block
+ id2var = dict([(var.get_id(), var) for var in variables])
+ #map var id to variable code
+ #variable code is a concatenation of all param code (without the id param)
+ id2expr = dict([(var.get_id(), get_variable_code(var)) for var in variables])
+ #sort according to dependency
+ sorted_ids = expr_utils.sort_variables(id2expr)
+ #create list of sorted variable blocks
+ variables = [id2var[id] for id in sorted_ids]
+ return variables
+
+ def get_parameters(self):
+ """
+ Get a list of all paramterized variables in this flow graph namespace.
+ @return a list of paramterized variables
+ """
+ parameters = filter(lambda b: b.get_key() == 'parameter', self.get_enabled_blocks())
+ return parameters
+
+ def evaluate(self, expr):
+ """
+ Evaluate the expression.
+ @param expr the string expression
+ @throw Exception bad expression
+ @return the evaluated data
+ """
+ if self.is_flagged():
+ self.deflag()
+ #reload namespace
+ n = dict()
+ #load imports
+ for imp in self.get_imports():
+ try: exec imp in n
+ except: pass
+ #load parameters
+ np = dict()
+ for parameter in self.get_parameters():
+ try:
+ e = eval(parameter.get_param('value').to_code(), n, n)
+ np[parameter.get_id()] = e
+ except: pass
+ n.update(np) #merge param namespace
+ #load variables
+ for variable in self.get_variables():
+ try:
+ e = eval(get_variable_code(variable), n, n)
+ n[variable.get_id()] = e
+ except: pass
+ #make namespace public
+ self.n = n
+ #evaluate
+ e = eval(expr, self.n, self.n)
+ return e