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-10-09 19:08:08 +0400
committerIan Johnson <ian.johnson@appliedlanguage.com>2013-10-09 19:08:08 +0400
commitc25101f03aced0408ec9e5d5b8f3c1b0bad91a29 (patch)
treec857a5f8f79e1fb4198807a992171328f19b74ad
parent408b85900ac1c84c3224f478da8f290c92ca328a (diff)
Grammar extended to accommodate do notation.
-rw-r--r--src/pclc/parser/component.py53
-rw-r--r--src/pclc/parser/expressions.py5
-rw-r--r--src/pclc/parser/import_spec.py2
-rw-r--r--src/pclc/parser/mappings.py13
-rw-r--r--src/pclc/parser/pcl_lexer.py7
-rw-r--r--src/pclc/parser/pcl_parser.py120
-rw-r--r--src/pclc/visitors/first_pass_resolver_visitor.py3
7 files changed, 185 insertions, 18 deletions
diff --git a/src/pclc/parser/component.py b/src/pclc/parser/component.py
index 229367b..b4ad6f3 100644
--- a/src/pclc/parser/component.py
+++ b/src/pclc/parser/component.py
@@ -27,7 +27,8 @@ class Component(Entity):
outputs,
configuration,
declarations,
- definition):
+ definition,
+ is_leaf):
Entity.__init__(self, filename, lineno)
self.identifier = identifier
self.inputs = inputs
@@ -35,6 +36,54 @@ class Component(Entity):
self.configuration = configuration
self.declarations = declarations
self.definition = definition
+ self.is_leaf = is_leaf
+
+ @staticmethod
+ def getLeafComponent(filename,
+ lineno,
+ identifier,
+ inputs,
+ outputs,
+ configuration,
+ do_commands):
+ class LeafDefinition(Entity):
+ def __init__(self):
+ self.filename = filename
+ self.lineno = do_commands[0].lineno
+ self.do_commands = do_commands
+
+ def accept(self, visitor):
+ for cmd in self.do_commands:
+ cmd.accept(visitor)
+
+ return Component(filename,
+ lineno,
+ identifier,
+ inputs,
+ outputs,
+ configuration,
+ list(),
+ LeafDefinition(),
+ True)
+
+ @staticmethod
+ def getNodeComponent(filename,
+ lineno,
+ identifier,
+ inputs,
+ outputs,
+ configuration,
+ declarations,
+ definition):
+ return Component(filename,
+ lineno,
+ identifier,
+ inputs,
+ outputs,
+ configuration,
+ declarations,
+ definition,
+ False)
def accept(self, visitor):
visitor.visit(self)
@@ -47,7 +96,7 @@ class Component(Entity):
def __repr__(self):
return "<Component:\n\tname = %s,\n\tinputs = %s,\n\toutputs = %s," \
- "\n\tconfiguration = %s,\n\tdeclarations = %s\n\tdefinition = %s" \
+ "\n\tconfiguration = %s,\n\tdeclarations = %s,\n\tdefinition = %s," \
"\n\tentity = %s>" % \
(self.identifier.__repr__(), self.inputs.__repr__(),
self.outputs.__repr__(), self.configuration.__repr__(),
diff --git a/src/pclc/parser/expressions.py b/src/pclc/parser/expressions.py
index bc430cd..b12411d 100644
--- a/src/pclc/parser/expressions.py
+++ b/src/pclc/parser/expressions.py
@@ -74,10 +74,13 @@ class StateIdentifier(Identifier):
def __init__(self, filename, lineno, identifier):
Identifier.__init__(self, filename, lineno, identifier)
+ def __str__(self):
+ return "@%s" % super(StateIdentifier, self).__str__()
+
def __repr__(self):
return "<StateIdentifier: identifier = %s, entity = %s>" % \
(self.identifier.__repr__(),
- super(Identifier, self).__repr__())
+ super(StateIdentifier, self).__repr__())
class Expression(Entity):
def __init__(self, filename, lineno, parent_expr = None):
diff --git a/src/pclc/parser/import_spec.py b/src/pclc/parser/import_spec.py
index a785cf8..328480e 100644
--- a/src/pclc/parser/import_spec.py
+++ b/src/pclc/parser/import_spec.py
@@ -25,7 +25,7 @@ class Import(Entity):
self.alias = alias
def __str__(self):
- return self.module_name
+ return str(self.module_name)
def __repr__(self):
return "<ImportSpec: module = [%s], alias = [%s], entity = %s>" % \
diff --git a/src/pclc/parser/mappings.py b/src/pclc/parser/mappings.py
index e8e85e8..5094ace 100644
--- a/src/pclc/parser/mappings.py
+++ b/src/pclc/parser/mappings.py
@@ -73,3 +73,16 @@ class LiteralMapping(Entity):
(self.literal.__repr__(),
self.to.__repr__(),
super(LiteralMapping, self).__repr__())
+
+class ReturnMapping(Mapping):
+ def __init__(self, filename, lineno, from_, to_identifier):
+ Mapping.__init__(self, filename, lineno, from_, to_identifier)
+
+ def __str__(self):
+ return "%s <- %s" % (self.to, self.from_)
+
+ def __repr__(self):
+ return "<ReturnMapping: from = %s,\n\tto = %s\n\tentity = %s>" % \
+ (self.from_.__repr__(),
+ self.to.__repr__(),
+ super(ReturnMapping, self).__repr__())
diff --git a/src/pclc/parser/pcl_lexer.py b/src/pclc/parser/pcl_lexer.py
index 9e36dc0..5a1563b 100644
--- a/src/pclc/parser/pcl_lexer.py
+++ b/src/pclc/parser/pcl_lexer.py
@@ -33,6 +33,9 @@ reserved = {
'component' : 'COMPONENT',
'configuration' : 'CONFIGURATION',
'declare' : 'DECLARE',
+ 'do' : 'DO',
+ 'endif' : 'ENDIF',
+ 'else' : 'ELSE',
'first' : 'FIRST',
'import' : 'IMPORT',
'if' : 'IF',
@@ -43,8 +46,10 @@ reserved = {
'or' : 'OR',
'output' : 'OUTPUTS',
'outputs' : 'OUTPUTS',
+ 'return' : 'RETURN',
'second' : 'SECOND',
'split' : 'SPLIT',
+ 'then' : 'THEN',
'top' : 'TOP',
'wire' : 'WIRE',
'with' : 'WITH',
@@ -58,6 +63,7 @@ tokens = [
'EQUALS',
'NOT_EQUALS',
'GT', 'LT', 'G_EQUAL', 'L_EQUAL',
+ 'LEFT_ARROW',
'QUALIFIED_IDENTIFIER', 'IDENTIFIER',
'COMPOSITION',
'FLOAT',
@@ -81,6 +87,7 @@ class PCLLexer(object):
t_LT = r'<'
t_G_EQUAL = r'>='
t_L_EQUAL = r'<='
+ t_LEFT_ARROW = r'<-'
t_COMPOSITION = r'>>>'
t_MAPS_TO = r'->'
t_PARALLEL_WITH_TUPLE = r'\*\*\*'
diff --git a/src/pclc/parser/pcl_parser.py b/src/pclc/parser/pcl_parser.py
index 8750dc3..d874891 100644
--- a/src/pclc/parser/pcl_parser.py
+++ b/src/pclc/parser/pcl_parser.py
@@ -26,6 +26,7 @@ from pcl_lexer import tokens, PCLLexer
from import_spec import Import
from component import Component
from declaration import Declaration
+from command import Command, Function, Return, IfCommand
from conditional_expressions import AndConditionalExpression, \
OrConditionalExpression, \
XorConditionalExpression, \
@@ -55,7 +56,8 @@ from expressions import Literal, \
from mappings import Mapping, \
TopMapping, \
BottomMapping, \
- LiteralMapping
+ LiteralMapping, \
+ ReturnMapping
from module import Module
@@ -95,15 +97,27 @@ def p_import_spec(p):
Identifier(p.parser.filename, p.lineno(4), p[4]))
def p_component_definition(p):
- '''component_definition : COMPONENT IDENTIFIER INPUTS scalar_or_tuple_identifier_comma_list OUTPUTS scalar_or_tuple_identifier_comma_list opt_configuration opt_declarations AS component_body_expression'''
- p[0] = Component(p.parser.filename,
- p.lineno(1),
- Identifier(p.parser.filename, p.lineno(2), p[2]),
- p[4],
- p[6],
- p[7],
- p[8],
- p[10])
+ '''component_definition : COMPONENT IDENTIFIER INPUTS scalar_or_tuple_identifier_comma_list OUTPUTS scalar_or_tuple_identifier_comma_list opt_configuration opt_declarations AS arrow_expression
+ | COMPONENT IDENTIFIER INPUTS scalar_or_tuple_identifier_comma_list OUTPUTS scalar_or_tuple_identifier_comma_list opt_configuration DO do_command_list'''
+ lineno = p.lineno(1)
+ identifier = Identifier(p.parser.filename, p.lineno(2), p[2])
+ if len(p) > 10:
+ p[0] = Component.getNodeComponent(p.parser.filename,
+ lineno,
+ identifier,
+ p[4],
+ p[6],
+ p[7],
+ p[8],
+ p[10])
+ else:
+ p[0] = Component.getLeafComponent(p.parser.filename,
+ lineno,
+ identifier,
+ p[4],
+ p[6],
+ p[7],
+ p[9])
def p_opt_configuration(p):
'''opt_configuration : CONFIGURATION identifier_comma_list
@@ -155,9 +169,13 @@ def p_mapping(p):
'''mapping : identifier_or_literal MAPS_TO identifier_or_qual_identifier'''
p[0] = Mapping(p.parser.filename, p[1].lineno, p[1], p[3])
-def p_component_body(p):
- '''component_body_expression : arrow_expression'''
- p[0] = p[1]
+##def p_body_expression_or_do_notation(p):
+## '''body_expression_or_do_notation : opt_declarations AS arrow_expression
+## | DO do_command_list'''
+## if len(p) > 2:
+## p[0] = [p[1], p[2]]
+## else:
+## p[0] = p[2]
def p_arrow_expression(p):
'''arrow_expression : composition_expression'''
@@ -356,6 +374,77 @@ def p_unary_conditional_expression(p):
else:
p[0] = TerminalConditionalExpression(p[1])
+def p_do_command_list(p):
+ '''do_command_list : do_command do_command_list
+ | do_command'''
+ if len(p) > 2:
+ p[0] = [p[1]] + p[2]
+ else:
+ p[0] = [p[1]]
+
+def p_do_command(p):
+ '''do_command : identifier_or_qual_identifier LEFT_ARROW function
+ | function
+ | RETURN return_mappings
+ | IF conditional_expression THEN do_command_list ELSE do_command_list ENDIF'''
+ if len(p) > 4:
+ p[0] = IfCommand(p.parser.filename, p.lineno(1), p[2], p[4], p[6])
+ elif len(p) > 3:
+ p[0] = Command(p.parser.filename, p[1].lineno, p[1], p[3])
+ elif len(p) > 2:
+ p[0] = Return(p.parser.filename, p.lineno(1), p[2])
+ else:
+ p[0] = Command(p.parser.filename, p[1].lineno, None, p[1])
+
+def p_function(p):
+ '''function : identifier_or_qual_identifier '(' opt_function_args ')' '''
+ p[0] = Function(p.parser.filename, p[1].lineno, p[1], p[3])
+
+def p_opt_function_args(p):
+ '''opt_function_args : function_arg_list
+ | '''
+ if len(p) > 0:
+ p[0] = p[1]
+ else:
+ p[0] = list()
+
+def p_function_arg_list(p):
+ '''function_arg_list : function_arg ',' function_arg_list
+ | function_arg'''
+ if len(p) > 2:
+ p[0] = [p[1]] + p[3]
+ else:
+ p[0] = [p[1]]
+
+def p_function_arg(p):
+ '''function_arg : identifier_or_literal
+ | state_identifier'''
+ p[0] = p[1]
+
+def p_return_mappings(p):
+ '''return_mappings : return_mapping_list
+ | '(' ')' '''
+ if len(p) > 1:
+ p[0] = list()
+ else:
+ p[0] = p[1]
+
+def p_return_mapping_list(p):
+ '''return_mapping_list : return_mapping ',' return_mapping_list
+ | return_mapping'''
+ if len(p) > 2:
+ p[0] = [p[1]] + p[3]
+ else:
+ p[0] = [p[1]]
+
+def p_return_mapping(p):
+ '''return_mapping : identifier_or_qual_identifier LEFT_ARROW identifier_or_literal
+ | identifier_or_qual_identifier LEFT_ARROW state_identifier'''
+ p[0] = ReturnMapping(p.parser.filename,
+ p[1].lineno,
+ p[3],
+ p[1])
+
def p_scalar_or_tuple_identifier_comma_list(p):
'''scalar_or_tuple_identifier_comma_list : '(' identifier_comma_list ')' ',' '(' identifier_comma_list ')'
| identifier_comma_list'''
@@ -398,7 +487,10 @@ recovery_tokens = (')',
'PARALLEL_WITH_TUPLE',
'PARALLEL_WITH_SCALAR',
'AS',
- 'DECLARE')
+ 'DECLARE',
+ 'DO',
+ 'IF',
+ 'RETURN')
def p_error(token):
if not token:
diff --git a/src/pclc/visitors/first_pass_resolver_visitor.py b/src/pclc/visitors/first_pass_resolver_visitor.py
index e7b1f3a..9ecbe24 100644
--- a/src/pclc/visitors/first_pass_resolver_visitor.py
+++ b/src/pclc/visitors/first_pass_resolver_visitor.py
@@ -122,6 +122,7 @@ class FirstPassResolverVisitor(ResolverVisitor):
python_module_interface = []
if declarations:
+ print "\n".join(map(lambda d: str(d), declarations))
for decl in declarations:
# Count occurrences of declaration identifiers
try:
@@ -305,6 +306,8 @@ class FirstPassResolverVisitor(ResolverVisitor):
# Mark the import as not used for now ;)
self._module.resolution_symbols['used_imports'][an_import.alias] = (an_import, False)
+ print self._errors
+
@multimethod(Component)
def visit(self, component):
# Component name *must* be the same as the file name