Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ianj-als/pcl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Johnson <ian.johnson@appliedlanguage.com>2013-05-21 19:33:48 +0400
committerIan Johnson <ian.johnson@appliedlanguage.com>2013-05-21 19:33:48 +0400
commita11ce00140323ef9fa1a5d26c6e4db05e461cc8d (patch)
tree8e15d8f6949d2d17c7ee7c0cc6113eda7a410b46 /src
parente6ac220310b6588102813b3bd8e2a6d769b20b7d (diff)
The configuration of a PCL file is now propagated through the pipeline. Any state conversions needed to support a imported component are done.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/pcl-run/pcl-run.py4
-rw-r--r--src/pclc/parser/pcl_lexer.py2
-rw-r--r--src/pclc/parser/pcl_parser.py2
-rwxr-xr-xsrc/pclc/pclc.py2
-rw-r--r--src/pclc/visitors/executor_visitor.py16
-rw-r--r--src/pclc/visitors/first_pass_resolver_visitor.py142
-rw-r--r--src/pclc/visitors/second_pass_resolver_visitor.py8
7 files changed, 97 insertions, 79 deletions
diff --git a/src/pcl-run/pcl-run.py b/src/pcl-run/pcl-run.py
index 35d9056..e5e91c8 100755
--- a/src/pcl-run/pcl-run.py
+++ b/src/pcl-run/pcl-run.py
@@ -27,7 +27,7 @@ from pypeline.core.arrows.kleisli_arrow import KleisliArrow
from pypeline.helpers.parallel_helpers import eval_pipeline, cons_function_component
-__VERSION = "1.0.1"
+__VERSION = "1.0.2"
def get_configuration(section, config_key):
@@ -153,6 +153,6 @@ if __name__ == '__main__':
executor = ThreadPoolExecutor(max_workers = options.no_workers)
print >> sys.stderr, "Evaluating pipeline..."
try:
- print eval_pipeline(executor, pipeline, pipeline_inputs, None)
+ print >> sys.stdout, eval_pipeline(executor, pipeline, pipeline_inputs, configuration)
finally:
executor.shutdown(True)
diff --git a/src/pclc/parser/pcl_lexer.py b/src/pclc/parser/pcl_lexer.py
index 0c5b85f..fc5ba6d 100644
--- a/src/pclc/parser/pcl_lexer.py
+++ b/src/pclc/parser/pcl_lexer.py
@@ -72,7 +72,7 @@ tokens = [
class PCLLexer(object):
tokens = tokens
- literals = ",()[]"
+ literals = ",()[]@"
t_ASSIGN = r':='
t_EQUALS = r'=='
diff --git a/src/pclc/parser/pcl_parser.py b/src/pclc/parser/pcl_parser.py
index 45d3cf1..68d245c 100644
--- a/src/pclc/parser/pcl_parser.py
+++ b/src/pclc/parser/pcl_parser.py
@@ -135,7 +135,7 @@ def p_declaration(p):
p.lineno(1),
Identifier(p.parser.filename, p.lineno(1), p[1]),
Identifier(p.parser.filename, p.lineno(4), p[4]),
- p[5])
+ p[5] if p[5] else list())
def p_opt_with_clause(p):
'''opt_with_clause : WITH configuration_mappings
diff --git a/src/pclc/pclc.py b/src/pclc/pclc.py
index 67a85b1..5b9572e 100755
--- a/src/pclc/pclc.py
+++ b/src/pclc/pclc.py
@@ -27,7 +27,7 @@ from parser.resolver import Resolver
from visitors.executor_visitor import ExecutorVisitor
-__VERSION = "1.0.4"
+__VERSION = "1.0.5"
if __name__ == '__main__':
diff --git a/src/pclc/visitors/executor_visitor.py b/src/pclc/visitors/executor_visitor.py
index 65f2217..27ac5a2 100644
--- a/src/pclc/visitors/executor_visitor.py
+++ b/src/pclc/visitors/executor_visitor.py
@@ -227,12 +227,26 @@ class ExecutorVisitor(object):
else m.literal) \
for cm in decl.configuration_mappings]))) \
for decl in self._module.resolution_symbols['components']]
+ # Guard against a module returning a non-Kleisli arrow type from initialise
component_decl_guards = ["%(id)s = %(id)s " \
"if isinstance(%(id)s, KleisliArrow) " \
"else cons_function_component(%(id)s)" % \
{'id' : decl.identifier} \
for decl in self._module.resolution_symbols['components']]
- initialise_fn = [t for pair in zip(component_initialisations, component_decl_guards) for t in pair]
+ # Wrap this component with any state conversion components
+ state_wrappers = ["%(id)s = ((cons_function_component(lambda a, s: a, state_mutator = lambda s: {%(state)s, '____prev_' : s})) >> %(id)s) >> cons_function_component(lambda a, s: a, state_mutator = lambda s: s['____prev_'])" % \
+ {'id' : decl.identifier,
+ 'state' : "%s" % (", ".join(["'%s' : %s" % \
+ (cm.to, \
+ "s['%s']" % cm.from_ \
+ if isinstance(cm.from_, Identifier) \
+ else cm.from_.value.__repr__() \
+ if isinstance(cm.from_.value, str) \
+ else m.literal) \
+ for cm in decl.configuration_mappings]))} if decl.configuration_mappings else ""
+ for decl in self._module.resolution_symbols['components']]
+ #
+ initialise_fn = [t for triple in zip(component_initialisations, component_decl_guards, state_wrappers) for t in triple]
# Store variables in variable table
for decl in self._module.resolution_symbols['components']:
self._var_table[IdentifierExpression(None,
diff --git a/src/pclc/visitors/first_pass_resolver_visitor.py b/src/pclc/visitors/first_pass_resolver_visitor.py
index d038879..c03c56a 100644
--- a/src/pclc/visitors/first_pass_resolver_visitor.py
+++ b/src/pclc/visitors/first_pass_resolver_visitor.py
@@ -38,6 +38,7 @@ from parser.conditional_expressions import AndConditionalExpression, \
from parser.declaration import Declaration
from parser.expressions import Literal, \
Identifier, \
+ StateIdentifier, \
Expression, \
UnaryExpression, \
BinaryExpression, \
@@ -167,7 +168,7 @@ class FirstPassResolverVisitor(ResolverVisitor):
duplicate_declarations = filter(lambda de: dups[de] > 1, dups)
return (tuple(missing_config),
- tuple(unused_config),
+ set(unused_config),
tuple(unknown_imports),
tuple(duplicate_declarations),
tuple(unknown_module_configuration),
@@ -192,7 +193,8 @@ class FirstPassResolverVisitor(ResolverVisitor):
self._module.resolution_symbols = {'imports' : dict(),
'components' : dict(),
'used_components' : dict(),
- 'configuration' : dict()}
+ 'configuration' : dict(),
+ 'unused_configuration' : list()}
@multimethod(Import)
def visit(self, an_import):
@@ -306,82 +308,67 @@ class FirstPassResolverVisitor(ResolverVisitor):
# Check that all the used configuration in declarations exist, and is used
missing_configuration, \
- unused_configuration, \
+ self._module.resolution_symbols['unused_configuration'], \
unknown_imports, \
duplicate_declarations, \
unknown_module_configuration, \
python_module_interace = FirstPassResolverVisitor.__check_declarations(component.configuration,
component.declarations,
component.module.resolution_symbols['imports'])
- if duplicate_inputs or \
- duplicate_outputs or \
- duplicate_config or \
- duplicate_decl_identifiers or \
- missing_configuration or \
- unused_configuration or \
- unknown_imports or \
- duplicate_declarations or \
- unknown_module_configuration or \
- python_module_interace:
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, input " \
- "declaration contains duplicate identifier %(entity)s",
- duplicate_inputs,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, output " \
- "declaration contains duplicate identifier %(entity)s",
- duplicate_outputs,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, configuration " \
- "declaration contains duplicate identifier %(entity)s",
- duplicate_config,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, component " \
- "declaration contains duplicate identifier %(entity)s",
- duplicate_decl_identifiers,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, component " \
- "configuration does not exist %(entity)s",
- missing_configuration,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_warnings("WARNING: %(filename)s at line %(lineno)d, component " \
- "configuration is not used %(entity)s",
- unused_configuration,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, import not found " \
- "in declaration of %(entity)s",
- unknown_imports,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, duplicate declaration " \
- "found %(entity)s",
- duplicate_declarations,
- lambda e: {'entity' : e,
- 'filename' : e.filename,
- 'lineno' : e.lineno})
- self._add_errors("ERROR: %(filename)s at line %(lineno)d, configuration %(entity)s " \
- "used which is not defined in module %(module_name)s",
- unknown_module_configuration,
- lambda e: {'entity' : e['config_map'].to,
- 'module_name' : e['module_name'],
- 'filename' : e['config_map'].filename,
- 'lineno' : e['config_map'].lineno})
- self._add_errors("ERROR: Python module %(module_name)s does not define " \
- "mandatory function %(missing_function)s",
- python_module_interace,
- lambda e: e)
+
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, input " \
+ "declaration contains duplicate identifier %(entity)s",
+ duplicate_inputs,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, output " \
+ "declaration contains duplicate identifier %(entity)s",
+ duplicate_outputs,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, configuration " \
+ "declaration contains duplicate identifier %(entity)s",
+ duplicate_config,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, component " \
+ "declaration contains duplicate identifier %(entity)s",
+ duplicate_decl_identifiers,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, component " \
+ "configuration does not exist %(entity)s",
+ missing_configuration,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, import not found " \
+ "in declaration of %(entity)s",
+ unknown_imports,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, duplicate declaration " \
+ "found %(entity)s",
+ duplicate_declarations,
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
+ self._add_errors("ERROR: %(filename)s at line %(lineno)d, configuration %(entity)s " \
+ "used which is not defined in module %(module_name)s",
+ unknown_module_configuration,
+ lambda e: {'entity' : e['config_map'].to,
+ 'module_name' : e['module_name'],
+ 'filename' : e['config_map'].filename,
+ 'lineno' : e['config_map'].lineno})
+ self._add_errors("ERROR: Python module %(module_name)s does not define " \
+ "mandatory function %(missing_function)s",
+ python_module_interace,
+ lambda e: e)
@multimethod(Declaration)
def visit(self, decl):
@@ -417,6 +404,12 @@ class FirstPassResolverVisitor(ResolverVisitor):
lambda e: {'filename' : e.filename,
'lineno' : e.lineno,
'component' : e})
+ self._add_warnings("WARNING: %(filename)s at line %(lineno)d, component " \
+ "configuration %(entity)s is not used",
+ self._module.resolution_symbols['unused_configuration'],
+ lambda e: {'entity' : e,
+ 'filename' : e.filename,
+ 'lineno' : e.lineno})
@multimethod(UnaryExpression)
def visit(self, unary_expr):
@@ -643,7 +636,10 @@ class FirstPassResolverVisitor(ResolverVisitor):
@multimethod(TerminalConditionalExpression)
def visit(self, term_cond_expr):
- pass
+ terminal = term_cond_expr.terminal
+ if isinstance(terminal, StateIdentifier) and \
+ terminal in self._module.resolution_symbols['unused_configuration']:
+ self._module.resolution_symbols['unused_configuration'].remove(terminal)
@multimethod(Mapping)
def visit(self, mapping):
diff --git a/src/pclc/visitors/second_pass_resolver_visitor.py b/src/pclc/visitors/second_pass_resolver_visitor.py
index 6d1cf49..1cd6ca6 100644
--- a/src/pclc/visitors/second_pass_resolver_visitor.py
+++ b/src/pclc/visitors/second_pass_resolver_visitor.py
@@ -51,6 +51,10 @@ class SecondPassResolverVisitor(FirstPassResolverVisitor):
def visit(self, decl):
pass
+ @multimethod(object)
+ def visit(self, nowt):
+ pass
+
def __derive_inputs(self, expr):
return self.__walk_expression(expr.parent, expr)
@@ -114,3 +118,7 @@ class SecondPassResolverVisitor(FirstPassResolverVisitor):
inputs = self.__derive_inputs(split_expr)
split_expr.resolution_symbols['inputs'] = inputs
split_expr.resolution_symbols['outputs'] = inputs >= (lambda ins: Just((ins, ins)))
+
+ @multimethod(TerminalConditionalExpression)
+ def visit(self, term_cond_expr):
+ pass