Skip to content

Commit 3c7a04d

Browse files
committed
ast_code_generator is updated: codegen generates prettified source codes.
1 parent 3fa0048 commit 3c7a04d

File tree

13 files changed

+78
-30
lines changed

13 files changed

+78
-30
lines changed

pyverilog/ast_code_generator/codegen.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import os
1212
import math
1313
import re
14+
import functools
1415
from jinja2 import Environment, FileSystemLoader
1516

1617
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) )
@@ -22,6 +23,22 @@
2223

2324
DEFAULT_TEMPLATE_DIR = os.path.dirname(os.path.abspath(__file__)) + '/template/'
2425

26+
#-------------------------------------------------------------------------------
27+
try:
28+
import textwrap
29+
indent = textwrap.indent
30+
except:
31+
def indent(text, prefix, predicate=None):
32+
if predicate is None: predicate = lambda x: x and not x.isspace()
33+
ret = []
34+
for line in text.split('\n'):
35+
if predicate(line):
36+
ret.append(prefix)
37+
ret.append(line)
38+
ret.append('\n')
39+
return ''.join(ret[:-1])
40+
41+
#-------------------------------------------------------------------------------
2542
class ConvertVisitor(object):
2643
def visit(self, node):
2744
method = 'visit_' + node.__class__.__name__
@@ -42,8 +59,9 @@ def escape(s):
4259
return s
4360

4461
class ASTCodeGenerator(ConvertVisitor):
45-
def __init__(self):
62+
def __init__(self, indentsize=2):
4663
self.env = Environment(loader=FileSystemLoader(DEFAULT_TEMPLATE_DIR))
64+
self.indent = functools.partial(indent, prefix=' '*indentsize)
4765

4866
def visit_Source(self, node):
4967
filename = getfilename(node)
@@ -66,13 +84,13 @@ def visit_Description(self, node):
6684
def visit_ModuleDef(self, node):
6785
filename = getfilename(node)
6886
template = self.env.get_template(filename)
69-
paramlist = self.visit(node.paramlist) if node.paramlist is not None else ''
70-
portlist = self.visit(node.portlist) if node.portlist is not None else ''
87+
paramlist = self.indent(self.visit(node.paramlist)) if node.paramlist is not None else ''
88+
portlist = self.indent(self.visit(node.portlist)) if node.portlist is not None else ''
7189
template_dict = {
7290
'modulename' : escape(node.name),
7391
'paramlist' : paramlist,
7492
'portlist' : portlist,
75-
'items' : [ self.visit(item) for item in node.items ] if node.items else (),
93+
'items' : [ self.indent(self.visit(item)) for item in node.items ] if node.items else (),
7694
}
7795
rslt = template.render(template_dict)
7896
return rslt
@@ -641,10 +659,12 @@ def visit_NonblockingSubstitution(self, node):
641659
def visit_IfStatement(self, node):
642660
filename = getfilename(node)
643661
template = self.env.get_template(filename)
662+
true_statement = '' if node.true_statement is None else self.visit(node.true_statement)
663+
false_statement = '' if node.false_statement is None else self.visit(node.false_statement)
644664
template_dict = {
645665
'cond' : self.visit(node.cond),
646-
'true_statement' : '' if node.true_statement is None else self.visit(node.true_statement),
647-
'false_statement' : '' if node.false_statement is None else self.visit(node.false_statement),
666+
'true_statement' : true_statement,
667+
'false_statement' : false_statement,
648668
}
649669
rslt = template.render(template_dict)
650670
return rslt
@@ -711,7 +731,7 @@ def visit_Block(self, node):
711731
template = self.env.get_template(filename)
712732
template_dict = {
713733
'scope' : '' if node.scope is None else escape(node.scope),
714-
'statements' : [ self.visit(statement) for statement in node.statements ],
734+
'statements' : [ self.indent(self.visit(statement)) for statement in node.statements ],
715735
}
716736
rslt = template.render(template_dict)
717737
return rslt
@@ -765,7 +785,7 @@ def visit_DelayStatement(self, node):
765785
def visit_InstanceList(self, node):
766786
filename = getfilename(node)
767787
template = self.env.get_template(filename)
768-
parameterlist = [ self.visit(param) for param in node.parameterlist ]
788+
parameterlist = [ self.indent(self.visit(param)) for param in node.parameterlist ]
769789
instances = [ self.visit(instance) for instance in node.instances ]
770790
template_dict = {
771791
'module' : escape(node.module),
@@ -781,7 +801,7 @@ def visit_Instance(self, node):
781801
filename = getfilename(node)
782802
template = self.env.get_template(filename)
783803
array = '' if node.array is None else self.visit(node.array)
784-
portlist = [ self.visit(port) for port in node.portlist ]
804+
portlist = [ self.indent(self.visit(port)) for port in node.portlist ]
785805
template_dict = {
786806
'name' : escape(node.name),
787807
'array' : array,
@@ -814,7 +834,7 @@ def visit_PortArg(self, node):
814834
def visit_Function(self, node):
815835
filename = getfilename(node)
816836
template = self.env.get_template(filename)
817-
statement = [ self.visit(s) for s in node.statement ]
837+
statement = [ self.indent(self.visit(s)) for s in node.statement ]
818838
template_dict = {
819839
'name' : escape(node.name),
820840
'retwidth' : self.visit(node.retwidth),
@@ -838,9 +858,10 @@ def visit_FunctionCall(self, node):
838858
def visit_Task(self, node):
839859
filename = getfilename(node)
840860
template = self.env.get_template(filename)
861+
statement = [ self.indent(self.visit(s)) for s in node.statement ]
841862
template_dict = {
842863
'name' : escape(node.name),
843-
'statement' : self.visit(node.statement),
864+
'statement' : statement,
844865
}
845866
rslt = template.render(template_dict)
846867
return rslt
@@ -931,7 +952,7 @@ def visit_ParallelBlock(self, node):
931952
template = self.env.get_template(filename)
932953
template_dict = {
933954
'scope' : '' if node.scope is None else escape(node.scope),
934-
'statements' : [ self.visit(statement) for statement in node.statements ],
955+
'statements' : [ self.indent(self.visit(statement)) for statement in node.statements ],
935956
}
936957
rslt = template.render(template_dict)
937958
return rslt
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
always @({{ sens_list }})
2-
{{ statement }}
1+
2+
always @({{ sens_list }}) {{ statement }}

pyverilog/ast_code_generator/template/block.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ begin{% if scope != '' %} : {{ scope }}{% endif %}
22
{%- for statement in statements %}
33
{{ statement }}
44
{%- endfor %}
5-
end
5+
end

pyverilog/ast_code_generator/template/casestatement.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ case({{ comp }})
22
{%- for case in caselist %}
33
{{ case }}
44
{%- endfor %}
5-
endcase
5+
endcase
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
for({{ pre }} {{ cond }}; {{ post }})
2-
{{ statement }}
1+
for({{ pre }} {{ cond }}; {{ post }}) {{ statement }}

pyverilog/ast_code_generator/template/function.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
function {{ retwidth }} {{ name }};
23
{%- for s in statement %}
34
{{ s }}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
generate
2-
{%- for item in items %}
3-
{{ item }}
4-
{%- endfor %}
5-
endgenerate
1+
2+
generate {% for item in items %}{{ item }}{% endfor %}
3+
endgenerate
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
if({{ cond }}) {{ true_statement }}
2-
{% if false_statement != '' %}else {{ false_statement }}{% endif %}
1+
if({{ cond }}) {{ true_statement }}
2+
{%- if true_statement[-1] != ' ' and true_statement[-1] != '\n' %} {% endif -%}
3+
{%- if true_statement.count('\n') == 0 and false_statement != '' %}
4+
{% endif -%}
5+
{%- if false_statement != '' %}else {{ false_statement }}{% endif -%}

pyverilog/ast_code_generator/template/instancelist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
{{ module }}
23
{%- if len_parameterlist > 0 %}
34
#({% for param in parameterlist %}

pyverilog/ast_code_generator/template/moduledef.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ module {{ modulename }}{% if paramlist != '' %} #
77
(
88
{{ portlist }}
99
);
10-
{%- for item in items %}
11-
{{ item }}
12-
{%- endfor %}
13-
endmodule
1410

11+
{% for item in items %}{{ item }}
12+
{% endfor %}
13+
endmodule

0 commit comments

Comments
 (0)