diff options
author | Ian Johnson <ianj@wgrids.com> | 2013-10-29 17:34:50 +0400 |
---|---|---|
committer | Ian Johnson <ianj@wgrids.com> | 2013-10-29 17:34:50 +0400 |
commit | bfe104d15ef943ad17b75c9415a6322aca28db6f (patch) | |
tree | 306feebbfe6607dce54c5f585cd1471790de97a2 | |
parent | 508d01633959a87b50257af4b69989cdbfd3f4c9 (diff) |
Code generation for leaf components done. Example added to parallel sleep example.
-rw-r--r-- | examples/parallel_sleep/sleep.pcl | 33 | ||||
-rw-r--r-- | src/pclc/visitors/do_executor_visitor.py | 26 | ||||
-rw-r--r-- | src/pclc/visitors/executor_visitor.py | 29 | ||||
-rw-r--r-- | src/pclc/visitors/first_pass_resolver_visitor.py | 2 | ||||
-rw-r--r-- | src/runtime/pcl/util/string.py | 2 |
5 files changed, 62 insertions, 30 deletions
diff --git a/examples/parallel_sleep/sleep.pcl b/examples/parallel_sleep/sleep.pcl new file mode 100644 index 0000000..038b108 --- /dev/null +++ b/examples/parallel_sleep/sleep.pcl @@ -0,0 +1,33 @@ +# +# Copyright Capita Translation and Interpreting 2013 +# +# This file is part of Pipeline Creation Language (PCL). +# +# Pipeline Creation Language (PCL) 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 3 of the License, or +# (at your option) any later version. +# +# Pipeline Creation Language (PCL) 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 Pipeline Creation Language (PCL). If not, see <http://www.gnu.org/licenses/>. +# +import pcl.system.process as process +import pcl.util.list as list +import pcl.util.string as string + +component sleep + input sleep_time + output complete + configuration sleep_command + do + cmd.list <- list.cons() + list.append(cmd.list, @sleep_command) + list.append(cmd.list, sleep_time) + cmd.line <- string.join(cmd.list, " ") + process.callAndCheck(cmd.line) + return complete <- True diff --git a/src/pclc/visitors/do_executor_visitor.py b/src/pclc/visitors/do_executor_visitor.py index e312095..b8969cb 100644 --- a/src/pclc/visitors/do_executor_visitor.py +++ b/src/pclc/visitors/do_executor_visitor.py @@ -123,22 +123,16 @@ class IntermediateRepresentation(object): def generate_code(self, executor_visitor, assignment_symbol_table): # Generate function call lambdas - generate_func_args = lambda args: ", ".join(["s['%s']" % a.identifier if isinstance(a, StateIdentifier) \ - else executor_visitor._lookup_var(a) if isinstance(a, Identifier) and \ - a in assignment_symbol_table \ - else "a['%s']" % a if isinstance(a, Identifier) \ - else str(a) for a in args]) + generate_func_args = lambda args: ", ".join([executor_visitor._generate_terminal(a) for a in args]) generate_func_call = lambda f: "____%s(%s)" % (f.name, generate_func_args(f.arguments)) code = list() for node in self.__root: - code.extend(self.__generate_code(node, generate_func_call, executor_visitor)) + code.extend(self.__generate_code(node, generate_func_call, executor_visitor, False)) - top_function_name = self.__lookup_function_name(self.__root[0].object) - - return (code, top_function_name) + return code - def __generate_code(self, node, generate_function_call, executor_visitor): + def __generate_code(self, node, generate_function_call, executor_visitor, is_value_returned = True): code = list() if isinstance(node, IntermediateRepresentation.IRCommandNode): @@ -156,7 +150,10 @@ class IntermediateRepresentation(object): code.extend(more_code) code.append((None, "-")) - code.append(("%s(a, s)" % self.__lookup_function_name(command), "")) + if is_value_returned: + code.append(("return %s(a, s)" % self.__lookup_function_name(command), "")) + else: + code.append(("return %s" % self.__lookup_function_name(command), "")) elif isinstance(node, IntermediateRepresentation.IRIfNode): # If command action code generation if_command = node.object @@ -180,6 +177,8 @@ class IntermediateRepresentation(object): return_command = node.object if len(return_command.mappings) == 0: code.append(("return None", "")) + else: + code.append(("return {%s}" % ", ".join(["'%s' : %s" % (m.to, executor_visitor._generate_terminal(m.from_)) for m in return_command.mappings]), "")) return code @@ -282,13 +281,10 @@ class DoExecutorVisitor(ExecutorVisitor): @multimethod(object) def visit(self, nowt): - func_defs, top_function_name = self.__ir.generate_code(self, self._module.resolution_symbols['assignment_table']) + func_defs = self.__ir.generate_code(self, self._module.resolution_symbols['assignment_table']) # Write initialise function self._write_function("initialise", func_defs, ["config"]) - self._reset_indent_level() - self._write_lines([("", "+")]) - self._write_line("return %s" % top_function_name) self._object_file.close() @multimethod(Function) diff --git a/src/pclc/visitors/executor_visitor.py b/src/pclc/visitors/executor_visitor.py index fc76256..e0255c6 100644 --- a/src/pclc/visitors/executor_visitor.py +++ b/src/pclc/visitors/executor_visitor.py @@ -114,22 +114,25 @@ class ExecutorVisitor(object): def _lookup_var(self, expr): return self._var_table[expr] + def _generate_terminal(self, terminal): + if isinstance(terminal, StateIdentifier): + return "s['%s']" % terminal.identifier + elif isinstance(terminal, Identifier) and \ + terminal in self._module.resolution_symbols['assignment_table']: + return self._lookup_var(terminal) + elif isinstance(terminal, Identifier): + return "a['%s']" % terminal + elif isinstance(terminal, Literal): + return str(terminal) + else: + print type(terminal) + raise ValueError("Unexpected terminal in conditional: filename = %s, line no = %d" % \ + (terminal.filename, terminal.lineno)) + def _generate_condition(self, cond_expr): # Terminal! if isinstance(cond_expr, TerminalConditionalExpression): - terminal = cond_expr.terminal - if isinstance(terminal, StateIdentifier): - return "s['%s']" % terminal - elif isinstance(terminal, Identifier) and \ - terminal in self._module.resolution_symbols['assignment_table']: - return self._lookup_var(terminal) - elif isinstance(terminal, Identifier): - return "a['%s']" % terminal - elif isinstance(terminal, Literal): - return str(terminal) - else: - raise ValueError("Unexpected terminal in conditional: filename = %s, line no = %d" % \ - (terminal.filename, terminal.lineno)) + return self._generate_terminal(cond_expr.terminal) elif isinstance(cond_expr, ConditionalExpression): left_code = self._generate_condition(cond_expr.left) right_code = self._generate_condition(cond_expr.right) diff --git a/src/pclc/visitors/first_pass_resolver_visitor.py b/src/pclc/visitors/first_pass_resolver_visitor.py index af04a23..fc369fc 100644 --- a/src/pclc/visitors/first_pass_resolver_visitor.py +++ b/src/pclc/visitors/first_pass_resolver_visitor.py @@ -968,7 +968,7 @@ class FirstPassResolverVisitor(ResolverVisitor): # Missing 'from' maps self._add_errors("ERROR: %(filename)s at line %(lineno)d, unknown variable in return %(unknown)s", - missing_froms, + [mf for mf in missing_froms if not isinstance(mf, Literal)], lambda m: {'filename' : m.filename, 'lineno' : m.lineno, 'unknown' : str(m)}) diff --git a/src/runtime/pcl/util/string.py b/src/runtime/pcl/util/string.py index 7ba1859..fbf3354 100644 --- a/src/runtime/pcl/util/string.py +++ b/src/runtime/pcl/util/string.py @@ -21,4 +21,4 @@ split = lambda s, ss: s.__str__().split(ss) # join :: [String] -> String -> String -join = lambda l, s: s.join(l) +join = lambda l, s: s.join([str(e) for e in l]) |