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
diff options
context:
space:
mode:
authorIan Johnson <ian.johnson@appliedlanguage.com>2013-07-02 18:13:11 +0400
committerIan Johnson <ian.johnson@appliedlanguage.com>2013-07-02 18:13:11 +0400
commit4aecfcffe8a236c36bbe2d8451e992015f3f7250 (patch)
tree2e233586e53a976c8c3fd0d2ef8ed25175c8f1cc
parent843a68990fd4497e3cc8159376cc4dede47087ae (diff)
Completed first draft of compiler documentation. Bug fixes to resolution code, grammar clean up, and better instrumentation logging.
-rw-r--r--documentation/chapters/background/background.tex1
-rw-r--r--documentation/chapters/compiler/compiler.tex87
-rw-r--r--documentation/chapters/compiler/diagrams/literal.pngbin23118 -> 23598 bytes
-rw-r--r--documentation/chapters/compiler/diagrams/pcl-grammar.ebnf2
-rw-r--r--documentation/chapters/run-time/run-time.tex7
-rw-r--r--documentation/pcl-manual.tex2
-rw-r--r--src/pclc/parser/expressions.py16
-rw-r--r--src/pclc/parser/pcl_lexer.py4
-rw-r--r--src/pclc/parser/pcl_parser.py8
-rwxr-xr-xsrc/pclc/pclc.py2
-rw-r--r--src/pclc/visitors/executor_visitor.py88
-rw-r--r--src/pclc/visitors/first_pass_resolver_visitor.py6
-rw-r--r--src/pclc/visitors/second_pass_resolver_visitor.py5
-rw-r--r--src/pclc/visitors/third_pass_resolver_visitor.py3
14 files changed, 139 insertions, 92 deletions
diff --git a/documentation/chapters/background/background.tex b/documentation/chapters/background/background.tex
deleted file mode 100644
index ef91110..0000000
--- a/documentation/chapters/background/background.tex
+++ /dev/null
@@ -1 +0,0 @@
-\chapter{Background}
diff --git a/documentation/chapters/compiler/compiler.tex b/documentation/chapters/compiler/compiler.tex
index 969441f..4b222de 100644
--- a/documentation/chapters/compiler/compiler.tex
+++ b/documentation/chapters/compiler/compiler.tex
@@ -34,7 +34,7 @@ The imported component is referenced using an identifier which can be fully qual
Each imported component must specify an alias. This is the name by which this component shall be referred to in this PCL file. E.g., \texttt{import components.utility.sleep as sleep\_comp} shall import a PCL component called \texttt{sleep} from the package \texttt{components.utility} and shall be refereed to as, i.e. has the alias, \texttt{sleep\_comp}.
-\subsection{Port Definition}
+\subsection{Port Definition}\label{subsec:port-def}
\begin{figure}[h!]
\centering
\includegraphics[scale=\DiagramScale,angle=90]{chapters/compiler/diagrams/port_definition}
@@ -87,7 +87,7 @@ component rainbow
\end {itemize}
-\subsection{Configuration}
+\subsection{Configuration}\label{subsec:config}
\begin{figure}[h!]
\centering
\includegraphics[scale=\DiagramScale]{chapters/compiler/diagrams/configuration}
@@ -112,7 +112,7 @@ component parallel_sleep
\label{fig:pcl-config-example}
\end{figure}
-\subsection{Declarations}
+\subsection{Declarations}\label{subsec:decls}
\begin{figure}[h!]
\centering
\includegraphics[scale=0.45]{chapters/compiler/diagrams/declarations}
@@ -203,7 +203,7 @@ The \texttt{\&\&\&} combinator yields a component with one input port and two ou
\begin{center}
$a\ \&\&\&\ b\ =\ split\ >>>\ (first\ a\ ***\ second\ b)$
\end{center}
-Since \texttt{split} is begin used both components, $a$ and $b$, require their input port signal to be compatible with the input to split.
+Since \texttt{split} is begin used both components, $a$ and $b$, require their input port signals to be compatible with the input to split.
Consider two components:
\begin{itemize}
@@ -218,7 +218,7 @@ Then $c_1\ \&\&\&\ c_2$ shall yield a one input and two output port component wi
PCLc verifies that components, used with the fanout combinator, have compatible ports and signals. The compiler will report errors if there are incompatible components used.
-\subsubsection{Merge}
+\subsubsection{Merge}\label{subsubsec:merge}
The merge component is a pre-defined component that expects a mapping and \emph{merges} the output from a two output port component to a single port component. Hence, a merge component has two input ports and one output port.
The merge mapping syntax is shown in Figure \ref{fig:pcl-merge-mapping}.
@@ -258,7 +258,7 @@ This merge mapping does the following:
\end{itemize}
Other constant literals can be used in a merge mapping and are described in Section \ref{sec:literals}.
-\subsubsection{Wire}
+\subsubsection{Wire}\label{subsubsec:wire}
Wire components are used to adapt one component's output signals to match the expected input signals of a subsequent component. Wires can only be used to adapt adjacent components that have an equal number of ports, i.e., the resultant wire component always has the same number of input ports as output ports. The \emph{wire mapping} determines whether a one or two port component is being adapted, this is shown in Figure \ref{fig:pcl-wire-mapping}.
\begin{figure}[h!]
\centering
@@ -357,24 +357,42 @@ component conditional
\end{center}
The \texttt{then\_component} shall only be executed if the input \texttt{a} is true or \texttt{a} and \texttt{b} are equal, and the configuration \texttt{f} is false.
-\subsection{Qualified Identifier}
-\begin{figure}[!h]
- \centering
- \includegraphics[scale=\DiagramScale,angle=90]{chapters/compiler/diagrams/qualified_identifier}
- \caption{\texttt{qualified\_identifier} : Qualified identifier.}
- \label{fig:pcl-qualified-id}
-\end{figure}
-
\subsection{Identifier}
-\begin{figure}[!h]
+In common with other programming languages PCL offers identifiers which can start with a letter or an underscore and then any number of letters, numbers or underscores, or diagrammatically see Figure \ref{fig:pcl-id}.
+\begin{figure}[h!]
\centering
\includegraphics[scale=\DiagramScale]{chapters/compiler/diagrams/identifier}
\caption{\texttt{identifier} : Identifier.}
\label{fig:pcl-id}
\end{figure}
+\subsection{Qualified Identifier}
+Qualified identifiers allows PCL developers to namespace their identifiers using dot separated identifiers, e.g., \texttt{tokeniser.source.filename}. Their syntax is shown in Figure \ref{fig:pcl-qualified-id}.
+\begin{figure}[h!]
+ \centering
+ \includegraphics[scale=\DiagramScale,angle=90]{chapters/compiler/diagrams/qualified_identifier}
+ \caption{\texttt{qualified\_identifier} : Qualified identifier.}
+ \label{fig:pcl-qualified-id}
+\end{figure}
+Qualified identifiers are available for use in:
+\begin{itemize}
+\item Imports: qualified identifiers are used to address compiled PCL components (see Section \ref{subsec:imports}),
+\item Port definitions: input and output signals can be namespaced for clarity (see Section \ref{subsec:port-def}),
+\item Configuration: configuration identifiers can be namespaced for clarity (see Section \ref{subsec:config}),
+\item Declarations: configuration mapping may required namespaced configuration to be used (see Section \ref{subsec:decls}),
+\item Merge and wire mappings: mapped port can contain namespaced signal names (see Section \ref{subsubsec:merge} and Section \ref{subsubsec:wire} respectively), and
+\item \emph{If} conditions: configuration used in \emph{if} condition expressions may be namespaced (see Section \ref{sec:if}).
+\end{itemize}
+
\subsection{Literal}\label{sec:literals}
-\begin{figure}[!h]
+Literal constants can be used to inject values into component constructors, merge and wire mappings, and \emph{if} condition expressions. They take the form of:
+\begin{itemize}
+\item Numbers: integer and floating point, e.g., \texttt{-7}, \texttt{2.71828}, \texttt{6.674e-11},
+\item Strings: string must be quoted using double quotes (\texttt{"}) and special characters can be escaped using a backslash (\textbackslash), e.g. \texttt{"This is a line of text\textbackslash n"}, and \texttt{"Quoting is \textbackslash"allowed\textbackslash" by escaping the quotes"}, and
+\item Booleans: \texttt{true} and \texttt{false}.
+\end{itemize}
+Figure \ref{fig:pcl-literal} shows their syntax.
+\begin{figure}[h!]
\centering
\includegraphics[scale=\DiagramScale,angle=90]{chapters/compiler/diagrams/literal}
\caption{\texttt{literal} : Literal.}
@@ -383,7 +401,7 @@ The \texttt{then\_component} shall only be executed if the input \texttt{a} is t
\subsection{Example PCL file}
This example PCL file can be found in the \texttt{parallel\_sleep} example PCL.
-\begin{figure}[!h]
+\begin{figure}[h!]
\begin{verbatim}
import sleep as sleep
@@ -399,5 +417,40 @@ component parallel_sleep
\end{verbatim}
\caption{Example PCL file.}
\end{figure}
+This component constructs two sleep components using a static sleep command to execute. The two sleep components are composed using the fanout operation, such that they run in parallel. Other example PCL files can be found in the \texttt{examples} directory of your Git clone.
\section{Usage}
+Ensure you have \texttt{src/pclc/pclc.py} in your platform path. Running \texttt{pclc.py -h} yields:
+\begin{verbatim}
+Usage: pclc.py [options] [PCL file]
+
+Options:
+ -h, --help show this help message and exit
+ -l LOGLEVEL, --loglevel=LOGLEVEL
+ parser log file reporting level
+ [default: WARN]
+ -i, --instrument Generated code shall instrument
+ components
+ -v, --version show version and exit
+\end{verbatim}
+
+The command-line options are:
+\begin{itemize}
+\item \texttt{-h}, \texttt{--help}: Display the help message,
+\item \texttt{-l}, \texttt{--loglevel}: The logging level for the \texttt{pclc.log} file that is created during compilation. This file, depending on log level, shall show information about the parsing internals of PCLc,
+\item \texttt{-i}, \texttt{--instrument}: Specifying this flag shall add code to the generated component which shall log to standard error when component starts and finishes. The log messages are time stamped so can be used as a rudimentary profiling tool, and
+\item \texttt{-v}, \texttt{--version}: Show the version of PCLc.
+\end{itemize}
+
+For example, change directory to \texttt{src/examples/parallel\_sleep} and issue the command:
+\begin{verbatim}
+pclc.py -i parallel_sleep.pcl
+\end{verbatim}
+The compilation process will generate three new files:
+\begin{itemize}
+\item \texttt{parallel\_sleep.py}: The object code from the compilation. PCL compiles to Python and this file shall be used by the runtime to build the final pipeline,
+\item \texttt{\_\_init\_\_.py}: Since the compiled PCL is a Python module, in order to import it at runtime PCLc must write this file to show that this is a Python package, and
+\item \texttt{pclc.log}: The log file for the compilation. This is mainly used for support but may be of interest to others.
+\end{itemize}
+
+In the next chapter you will see how to run pipelines using the Python based runtime.
diff --git a/documentation/chapters/compiler/diagrams/literal.png b/documentation/chapters/compiler/diagrams/literal.png
index b36b73e..df43d80 100644
--- a/documentation/chapters/compiler/diagrams/literal.png
+++ b/documentation/chapters/compiler/diagrams/literal.png
Binary files differ
diff --git a/documentation/chapters/compiler/diagrams/pcl-grammar.ebnf b/documentation/chapters/compiler/diagrams/pcl-grammar.ebnf
index 5a571ff..a6c32b2 100644
--- a/documentation/chapters/compiler/diagrams/pcl-grammar.ebnf
+++ b/documentation/chapters/compiler/diagrams/pcl-grammar.ebnf
@@ -26,4 +26,4 @@ qualified_identifier ::= [a-zA-Z_][a-zA-Z0-9_]*('.'[a-zA-Z_][a-zA-Z0-9_]*)+
identifier ::= [a-zA-Z_][a-zA-Z0-9_]*
-literal ::= [-]?[0-9]+('.'[0-9]+([eE][-+][0-9]+)?)? | '"' ('\'.|[^"])* '"' | [Tt][Rr][Uu][Ee] | [Ff][Aa][Ll][Ss][Ee] \ No newline at end of file
+literal ::= [-]?[0-9]+('.'[0-9]+([eE][-+]?[0-9]+)?)? | '"' ('\'.|[^"])* '"' | [Tt][Rr][Uu][Ee] | [Ff][Aa][Ll][Ss][Ee] \ No newline at end of file
diff --git a/documentation/chapters/run-time/run-time.tex b/documentation/chapters/run-time/run-time.tex
index 517eb79..d401b58 100644
--- a/documentation/chapters/run-time/run-time.tex
+++ b/documentation/chapters/run-time/run-time.tex
@@ -1 +1,8 @@
\chapter{PCL Runtime}
+
+
+\subsection{Gotchas}
+PCL allows for components to be defined in hierarchical namespace. All directories that do not contain PCL files must contain \texttt{\_\_init\_\_.py} in order for the Python runtime to ``see'' these directories as Python packages. Failure to do so will yield an error in the form:
+\begin{verbatim}
+ERROR: Failed to import PCL module parallel_sleep: No module named parallel_sleep
+\end{verbatim}
diff --git a/documentation/pcl-manual.tex b/documentation/pcl-manual.tex
index d84285f..e2cbd06 100644
--- a/documentation/pcl-manual.tex
+++ b/documentation/pcl-manual.tex
@@ -6,7 +6,6 @@
\documentclass[11pt,a4paper,openright]{report}
\includeonly{%
chapters/introduction/introduction,
- chapters/background/background,
chapters/compiler/compiler,
chapters/run-time/run-time
}
@@ -80,7 +79,6 @@ PCL was developed as part of the MosesCore project sponsored by the European Com
\pagenumbering{arabic}
\include{chapters/introduction/introduction}
-\include{chapters/background/background}
\include{chapters/compiler/compiler}
\include{chapters/run-time/run-time}
diff --git a/src/pclc/parser/expressions.py b/src/pclc/parser/expressions.py
index 5862754..bc430cd 100644
--- a/src/pclc/parser/expressions.py
+++ b/src/pclc/parser/expressions.py
@@ -286,19 +286,3 @@ class IdentifierExpression(Expression):
def __eq__(self, other):
return self.identifier.__eq__(other.identifier)
-
-class LiteralExpression(Expression):
- def __init__(self, filename, lineno, literal):
- Expression.__init__(self, filename, lineno)
- self.literal = literal
-
- def accept(self, visitor):
- visitor.visit(self)
-
- def __str__(self):
- return str(self.literal)
-
- def __repr__(self):
- return "<LiteralExpression:\n\tliteral = %s,\n\texpression = %s>" % \
- (self.literal.__repr__(),
- super(LiteralExpression, self).__repr__())
diff --git a/src/pclc/parser/pcl_lexer.py b/src/pclc/parser/pcl_lexer.py
index fc5ba6d..9e36dc0 100644
--- a/src/pclc/parser/pcl_lexer.py
+++ b/src/pclc/parser/pcl_lexer.py
@@ -76,7 +76,7 @@ class PCLLexer(object):
t_ASSIGN = r':='
t_EQUALS = r'=='
- t_NOT_EQUALS = r'!="'
+ t_NOT_EQUALS = r'!='
t_GT = r'>'
t_LT = r'<'
t_G_EQUAL = r'>='
@@ -104,7 +104,7 @@ class PCLLexer(object):
return t
def t_FLOAT(self, t):
- r'[-]?\d+\.\d+([eE][-+]\d+)?'
+ r'[-]?\d+\.\d+([eE][-+]?\d+)?'
t.value = float(t.value)
return t
diff --git a/src/pclc/parser/pcl_parser.py b/src/pclc/parser/pcl_parser.py
index 88e97c7..8750dc3 100644
--- a/src/pclc/parser/pcl_parser.py
+++ b/src/pclc/parser/pcl_parser.py
@@ -51,8 +51,7 @@ from expressions import Literal, \
WireExpression, \
WireTupleExpression, \
IfExpression, \
- IdentifierExpression, \
- LiteralExpression
+ IdentifierExpression
from mappings import Mapping, \
TopMapping, \
BottomMapping, \
@@ -196,7 +195,6 @@ def p_unary_expression(p):
| wire_expression
| if_expression
| identifier_expression
- | literal_expression
| '(' arrow_expression ')' '''
if len(p) > 2:
p[0] = UnaryExpression(p.parser.filename, p[2].lineno, p[2])
@@ -238,10 +236,6 @@ def p_identifier_expression(p):
'''identifier_expression : identifier_or_qual_identifier'''
p[0] = IdentifierExpression(p.parser.filename, p[1].lineno, p[1])
-def p_literal_expression(p):
- '''literal_expression : literal'''
- p[0] = LiteralExpression(p.parser.filename, p[1].lineno, p[1])
-
def p_merge_mappings(p):
'''merge_mappings : merge_mapping ',' merge_mappings
| merge_mapping'''
diff --git a/src/pclc/pclc.py b/src/pclc/pclc.py
index 0bea0f4..0a45c07 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.1.5"
+__VERSION = "1.1.6"
if __name__ == '__main__':
diff --git a/src/pclc/visitors/executor_visitor.py b/src/pclc/visitors/executor_visitor.py
index 4c45acf..1732366 100644
--- a/src/pclc/visitors/executor_visitor.py
+++ b/src/pclc/visitors/executor_visitor.py
@@ -50,8 +50,7 @@ from parser.expressions import Literal, \
WireExpression, \
WireTupleExpression, \
IfExpression, \
- IdentifierExpression, \
- LiteralExpression
+ IdentifierExpression
from parser.mappings import Mapping, \
TopMapping, \
BottomMapping, \
@@ -73,10 +72,12 @@ class ExecutorVisitor(object):
"from pypeline.core.arrows.kleisli_arrow_choice import KleisliArrowChoice\n" \
"from pypeline.core.types.either import Left, Right\n" \
"from pypeline.core.types.state import return_\n"
- __INSTRUMENTATION_FUNCTION = "import sys, threading, datetime\n" \
- "def ____instr_component(invoked_component, component_id, event, a):\n" \
- " print >> sys.stderr, '%s: %s: Component %s (id = %s) is %s' % (datetime.datetime.now().strftime('%x %X.%f'), threading.current_thread().name, invoked_component, component_id, event)\n" \
- " return a\n"
+ __INSTRUMENTATION_FUNCTIONS = "import sys, threading, datetime\n" \
+ "def ____instr_component(component_decl_id, component_id, event, a, s):\n" \
+ " print >> sys.stderr, '%s: %s: Component %s is %s %s (id = %s) with input %s and state %s' % (datetime.datetime.now().strftime('%x %X.%f'), threading.current_thread().name, get_name(), event, component_decl_id, component_id, a, {skey : s[skey] for skey in filter(lambda k: k != '____prev_', s.keys())})\n" \
+ " return a\n"\
+ "def ____instr_component_construction(component_decl_id, component_id, component_config, invoked_component, decl_line_no):\n" \
+ " print >> sys.stderr, '%s: %s: Component %s is constructing %s (id = %s) with configuration %s (%s instance declared at line %d)' % (datetime.datetime.now().strftime('%x %X.%f'), threading.current_thread().name, get_name(), component_decl_id, component_id, component_config, invoked_component, decl_line_no)\n"
__TEMP_VAR = "____tmp_%d"
def __init__(self, filename_root, is_instrumented = False):
@@ -93,7 +94,7 @@ class ExecutorVisitor(object):
self.__write_line(ExecutorVisitor.__HEADER % header_args)
self.__is_instrumented = is_instrumented
if self.__is_instrumented:
- self.__write_line(ExecutorVisitor.__INSTRUMENTATION_FUNCTION)
+ self.__write_line(ExecutorVisitor.__INSTRUMENTATION_FUNCTIONS)
self.__write_line()
self.__conditional_operators = {AndConditionalExpression : 'and',
OrConditionalExpression : 'or',
@@ -162,7 +163,7 @@ class ExecutorVisitor(object):
elif isinstance(terminal, Identifier):
return "a['%s']" % terminal
elif isinstance(terminal, Literal):
- return str(terminal)
+ return str(terminal).__repr__()
else:
raise ValueError("Unexpected terminal in conditional: filename = %s, line no = %d" % \
(terminal.filename, terminal.lineno))
@@ -221,19 +222,22 @@ class ExecutorVisitor(object):
for i in self._module.resolution_symbols['configuration']]),
["args"])
+ # Component configuration
+ component_configuration_exprs = ["%s_configuration = %s" % \
+ (decl.identifier,
+ "{%s}" % (", ".join(["'%s' : %s" % \
+ (cm.to, \
+ "config['%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]))) \
+ for decl in self._module.resolution_symbols['components']]
# The initialise function
- component_initialisations = ["%s = ____%s.initialise(____%s.configure(%s))" % \
- (decl.identifier,
- decl.component_alias,
- decl.component_alias,
- "{%s}" % (", ".join(["'%s' : %s" % \
- (cm.to, \
- "config['%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]))) \
+ component_initialisations = ["%(id)s = ____%(comp_alias)s.initialise(____%(comp_alias)s.configure(%(id)s_configuration))" % \
+ {'id' : decl.identifier,
+ 'comp_alias' : decl.component_alias} \
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 " \
@@ -241,14 +245,6 @@ class ExecutorVisitor(object):
"else cons_function_component(%(id)s)" % \
{'id' : decl.identifier} \
for decl in self._module.resolution_symbols['components']]
- # Wrap with instrumentation, if required
- if self.__is_instrumented:
- component_instrumentation_exprs = ["%(id)s = ((cons_function_component(lambda a, s: ____instr_component(____%(comp_alias)s.get_name(), id(%(id)s), 'starting', a)) >> " \
- "%(id)s) >> " \
- "cons_function_component(lambda a, s: ____instr_component(____%(comp_alias)s.get_name(), id(%(id)s), 'finishing', a)))" % \
- {'id' : decl.identifier,
- 'comp_alias' : decl.component_alias} \
- for decl in self._module.resolution_symbols['components']]
# 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,
@@ -263,9 +259,37 @@ class ExecutorVisitor(object):
for decl in self._module.resolution_symbols['components']]
# Do we generate instrumented code?
if self.__is_instrumented:
- decl_zipper = zip(component_initialisations, component_decl_guards, component_instrumentation_exprs, state_wrappers)
+ # Constructed component identifier
+ component_id_exprs = ["%(id)s_id = id(%(id)s)" % \
+ {'id' : decl.identifier} \
+ for decl in self._module.resolution_symbols['components']]
+ # Instrument component construction
+ component_init_instrumentation_exprs = ["____instr_component_construction('%(id)s', %(id)s_id, %(id)s_configuration, ____%(comp_alias)s.get_name(), %(decl_line_no)d)" % \
+ {'id' : decl.identifier,
+ 'comp_alias' : decl.component_alias,
+ 'decl_line_no' : decl.lineno} \
+ for decl in self._module.resolution_symbols['components']]
+ # Wrap with instrumentation
+ component_instrumentation_exprs = ["%(id)s = ((cons_function_component(lambda a, s: ____instr_component('%(id)s', %(id)s_id, 'starting', a, s)) >> " \
+ "%(id)s) >> " \
+ "cons_function_component(lambda a, s: ____instr_component('%(id)s', %(id)s_id, 'finishing', a, s)))" % \
+ {'id' : decl.identifier,
+ 'comp_alias' : decl.component_alias,
+ 'decl_line_no' : decl.lineno} \
+ for decl in self._module.resolution_symbols['components']]
+ # Generated code zipper
+ decl_zipper = zip(component_configuration_exprs,
+ component_initialisations,
+ component_decl_guards,
+ component_id_exprs,
+ component_init_instrumentation_exprs,
+ component_instrumentation_exprs,
+ state_wrappers)
else:
- decl_zipper = zip(component_initialisations, component_decl_guards, state_wrappers)
+ decl_zipper = zip(component_configuration_exprs,
+ component_initialisations,
+ component_decl_guards,
+ state_wrappers)
initialise_fn = [t for triple in decl_zipper for t in triple]
# Store variables in variable table
for decl in self._module.resolution_symbols['components']:
@@ -441,7 +465,3 @@ class ExecutorVisitor(object):
@multimethod(IdentifierExpression)
def visit(self, iden_expr):
pass
-
- @multimethod(LiteralExpression)
- def visit(self, literal_expr):
- pass
diff --git a/src/pclc/visitors/first_pass_resolver_visitor.py b/src/pclc/visitors/first_pass_resolver_visitor.py
index 08c2e33..e7b1f3a 100644
--- a/src/pclc/visitors/first_pass_resolver_visitor.py
+++ b/src/pclc/visitors/first_pass_resolver_visitor.py
@@ -52,8 +52,7 @@ from parser.expressions import Literal, \
WireExpression, \
WireTupleExpression, \
IfExpression, \
- IdentifierExpression, \
- LiteralExpression
+ IdentifierExpression
from parser.mappings import Mapping, \
TopMapping, \
BottomMapping, \
@@ -742,6 +741,3 @@ class FirstPassResolverVisitor(ResolverVisitor):
iden_expr.resolution_symbols['inputs'] = transform_fn(inputs)
iden_expr.resolution_symbols['outputs'] = transform_fn(outputs)
- @multimethod(LiteralExpression)
- def visit(self, literal_expr):
- pass
diff --git a/src/pclc/visitors/second_pass_resolver_visitor.py b/src/pclc/visitors/second_pass_resolver_visitor.py
index 8d288c3..a470e0b 100644
--- a/src/pclc/visitors/second_pass_resolver_visitor.py
+++ b/src/pclc/visitors/second_pass_resolver_visitor.py
@@ -32,7 +32,7 @@ from parser.expressions import UnaryExpression, \
SplitExpression
from pypeline.core.types.just import Just
from pypeline.core.types.nothing import Nothing
-from first_pass_resolver_visitor import FirstPassResolverVisitor, resolve_expression_once
+from first_pass_resolver_visitor import FirstPassResolverVisitor
@multimethodclass
@@ -86,7 +86,6 @@ class SecondPassResolverVisitor(FirstPassResolverVisitor):
return self.__walk_expression(node.parent, node)
@multimethod(FirstExpression)
- @resolve_expression_once
def visit(self, first_expr):
top_inputs = first_expr.expression.resolution_symbols['inputs']
top_outputs = first_expr.expression.resolution_symbols['outputs']
@@ -102,7 +101,6 @@ class SecondPassResolverVisitor(FirstPassResolverVisitor):
(lambda bouts: Just((touts, bouts))))
@multimethod(SecondExpression)
- @resolve_expression_once
def visit(self, second_expr):
# Derive the top inputs
inputs = self.__derive_inputs(second_expr)
@@ -117,7 +115,6 @@ class SecondPassResolverVisitor(FirstPassResolverVisitor):
(lambda bouts: Just((touts, bouts))))
@multimethod(SplitExpression)
- @resolve_expression_once
def visit(self, split_expr):
# Derive the inputs
inputs = self.__derive_inputs(split_expr)
diff --git a/src/pclc/visitors/third_pass_resolver_visitor.py b/src/pclc/visitors/third_pass_resolver_visitor.py
index 11b46de..e186d58 100644
--- a/src/pclc/visitors/third_pass_resolver_visitor.py
+++ b/src/pclc/visitors/third_pass_resolver_visitor.py
@@ -38,7 +38,7 @@ from parser.expressions import CompositionExpression, \
StateIdentifier
from pypeline.core.types.just import Just
from pypeline.core.types.nothing import Nothing
-from first_pass_resolver_visitor import resolve_expression_once, type_formatting_fn
+from first_pass_resolver_visitor import type_formatting_fn
from second_pass_resolver_visitor import SecondPassResolverVisitor
@@ -114,7 +114,6 @@ class ThirdPassResolverVisitor(SecondPassResolverVisitor):
'bottom_inputs' : bottom_inputs >= type_formatting_fn})
@multimethod(IfExpression)
- @resolve_expression_once
def visit(self, if_expr):
# Store the current if expression for condition expression resolution
self._current_if_expr = if_expr