Skip to content

Commit

Permalink
Merge branch 'ast_indent' into 'master'
Browse files Browse the repository at this point in the history
AST/ASR printing improved

Closes lcompilers#304

See merge request lfortran/lfortran!765
  • Loading branch information
certik committed Apr 12, 2021
2 parents eb10f6c + d5e247d commit 67bdb41
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 11 deletions.
49 changes: 38 additions & 11 deletions grammar/asdl_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,10 @@ def visitModule(self, mod):
self.emit("public:")
self.emit( "std::string s, indtd;", 1)
self.emit( "bool use_colors;", 1)
self.emit( "bool indent;", 1)
self.emit( "int indent_level = 0, indent_spaces = 3;", 1)
self.emit( "bool indent, start_line = true;", 1)
self.emit( "int indent_level = 0, indent_spaces = 3, lvl = 0;", 1)
self.emit( "int tmp = 0, tmp1 = 0, tmp2 = 2;", 1)
self.emit( "int curly[20], round[20];", 1)
self.emit("public:")
self.emit( "PickleBaseVisitor() : use_colors(false), indent(false) { s.reserve(100000); }", 1)
self.emit( "void inc_indent() {", 1)
Expand All @@ -425,6 +427,7 @@ def visitModule(self, mod):
self.emit( "}",1)
self.emit( "void dec_indent() {", 1)
self.emit( "indent_level--;", 2)
self.emit( "LFORTRAN_ASSERT(indent_level >= 0);", 2)
self.emit( "indtd = std::string(indent_level*indent_spaces, ' ');",2)
self.emit( "}",1)
self.mod = mod
Expand Down Expand Up @@ -452,8 +455,16 @@ def visitConstructor(self, cons, _):
def make_visitor(self, name, fields, cons):
self.emit("void visit_%s(const %s_t &x) {" % (name, name), 1)
self.emit( 'if(indent) {',2)
self.emit( 's.append("\\n"+indtd);', 3)
self.emit( 'inc_indent();',3)
self.emit( 'tmp1++;',3)
self.emit( 'round[tmp1] = indent_level;',3)
self.emit( 'if(start_line) {',3)
self.emit( 'start_line = false;', 4)
self.emit( 's.append(indtd);', 4)
self.emit( 'inc_indent();',4)
self.emit( '} else {', 3)
self.emit( 's.append("\\n"+indtd);', 4)
self.emit( 'inc_indent();',4)
self.emit( '}', 3)
self.emit( '}', 2)
self.emit( 's.append("(");', 2)
subs = {
Expand All @@ -479,6 +490,11 @@ def make_visitor(self, name, fields, cons):
self.visitField(field, cons)
if n < len(fields) - 1:
self.emit( 's.append(" ");', 2)
self.emit( 'if(indent) {', 2)
self.emit( 'lvl = indent_level;', 3)
self.emit( 'for(int times = 0; times < (lvl - round[tmp1] ); times++)', 3)
self.emit( 'dec_indent();', 4)
self.emit( 'round[tmp1] = 0; if(tmp1 > 1) tmp1--;}', 3)
self.emit( 's.append(")");', 2)
if not self.used:
# Note: a better solution would be to change `&x` to `& /* x */`
Expand All @@ -495,10 +511,7 @@ def make_simple_sum_visitor(self, name, types):
self.emit( 'switch (x) {', 2)
for tp in types:
self.emit( 'case (%s::%s) : {' % (name, tp.name), 3)
self.emit( 'if(indent) {',4)
self.emit( 'dec_indent();',5)
self.emit( 's.append("\\n"+indtd);', 5)
self.emit( '}', 4)
self.emit( 'if(indent) s.append("\\n"+indtd);',4)
self.emit( 's.append("%s");' % (tp.name), 4)
self.emit( ' break; }',3)
self.emit( '}', 2)
Expand Down Expand Up @@ -582,6 +595,7 @@ def visitField(self, field, cons):
level = 2
self.emit( 'if(indent) {',level)
self.emit( 's.append("\\n"+indtd);', level+1)
self.emit( 'round[++tmp1] = indent_level;',level+1)
self.emit( 'inc_indent();',level+1)
self.emit( '}', level)
self.emit( 's.append("(");', level)
Expand All @@ -598,6 +612,8 @@ def visitField(self, field, cons):
self.emit( 's.append(" ");', level)
self.emit( 'if(indent) {',level)
self.emit( 's.append("\\n"+indtd);', level+1)
self.emit( 'curly[++tmp] = indent_level;',level+1)
self.emit( 'tmp2 = 1;',level+1)
self.emit( 'inc_indent();',level+1)
self.emit( '}', level)
self.emit( 's.append("{");', level)
Expand All @@ -610,15 +626,26 @@ def visitField(self, field, cons):
self.emit( '}', level)
self.emit(' s.append(a.first + ": ");', level)
self.emit(' this->visit_symbol(*a.second);', level)
self.emit(' if (i < x.m_%s->scope.size()-1) s.append(", ");' % field.name, level)
self.emit(' if (i < x.m_%s->scope.size()-1) { ' % field.name, level)
self.emit(' s.append(", ");', level)
self.emit(' if(indent) {', level)
self.emit(' for(int times = 0; times < tmp2; times++)', level+1)
self.emit(' dec_indent();', level)
self.emit(' }', level)
self.emit(' }', level)
self.emit(' i++;', level)
self.emit(' }', level)
self.emit('}', level)
self.emit( 'if(indent){',level)
self.emit( 'dec_indent();', level+1)
self.emit( 'if(indent) {',level)
self.emit( 'lvl = indent_level;', level+1)
self.emit( 'for(int times = 0; times < (lvl - curly[tmp] ); times++)', level+1)
self.emit( 'dec_indent();', level+2)
self.emit( 'curly[tmp] = 0; if(tmp > 1) tmp--;', level+1)
self.emit( 'tmp2++;', level+1)
self.emit( 's.append("\\n"+indtd);', level+1)
self.emit( '}', level)
self.emit( 's.append("})");', level)
self.emit( 'if(indent) dec_indent();', level)
elif field.type == "string" and not field.seq:
if field.opt:
self.emit("if (x.m_%s) {" % field.name, 2)
Expand Down
9 changes: 9 additions & 0 deletions run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ def main():
continue
tokens = test.get("tokens", False)
ast = test.get("ast", False)
ast_indent = test.get("ast_indent", False)
ast_f90 = test.get("ast_f90", False)
ast_cpp = test.get("ast_cpp", False)
ast_cpp_hip = test.get("ast_cpp_hip", False)
ast_openmp = test.get("ast_openmp", False)
asr = test.get("asr", False)
asr_indent = test.get("asr_indent", False)
mod_to_asr = test.get("mod_to_asr", False)
llvm = test.get("llvm", False)
cpp = test.get("cpp", False)
Expand All @@ -64,6 +66,9 @@ def main():
if ast:
run_test("ast", "lfortran --show-ast --no-color {infile} -o {outfile}",
filename, update_reference)
if ast_indent:
run_test("ast_indent", "lfortran --show-ast --indent --no-color {infile} -o {outfile}",
filename, update_reference)

if ast_f90:
run_test("ast_f90", "lfortran --show-ast-f90 --no-color {infile}",
Expand All @@ -77,6 +82,10 @@ def main():
run_test("asr", "lfortran --show-asr --no-color {infile} -o {outfile}",
filename, update_reference)

if asr_indent:
run_test("asr_indent", "lfortran --show-asr --indent --no-color {infile} -o {outfile}",
filename, update_reference)

if mod_to_asr:
run_test("mod_to_asr", "lfortran mod --show-asr --no-color {infile}",
filename, update_reference)
Expand Down
13 changes: 13 additions & 0 deletions tests/reference/asr_indent-subroutine1-5dfc71f.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "asr_indent-subroutine1-5dfc71f",
"cmd": "lfortran --show-asr --indent --no-color {infile} -o {outfile}",
"infile": "tests/subroutine1.f90",
"infile_hash": "e209c22328b423e75d6801f3c0ef19bc120936196435dff2cb19df31",
"outfile": null,
"outfile_hash": null,
"stdout": "asr_indent-subroutine1-5dfc71f.stdout",
"stdout_hash": "7132f2d438e25d60076581c69bfdd21cf81fe825635e154d83f523e8",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
90 changes: 90 additions & 0 deletions tests/reference/asr_indent-subroutine1-5dfc71f.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
(TranslationUnit
(SymbolTable
1
{
g:
(Subroutine
(SymbolTable
2
{
i:
(Variable
2
i
Local ()
Default
(Integer 4 [])
Source
Public),
x:
(Variable
2
x
Local ()
Default
(Integer 4 [])
Source
Public)
})
g [] [
(=
(Var 2 x) (ConstantInteger 1
(Integer 4 [])))
(DoLoop
(
(Var 2 i) (ConstantInteger 1
(Integer 4 [])) (ConstantInteger 10
(Integer 4 [])) ()) [
(=
(Var 2 x)
(BinOp
(Var 2 x)
Mul
(Var 2 i)
(Integer 4 [])))])]
Source
Public),
h:
(Subroutine
(SymbolTable
3
{
i:
(Variable
3
i
Local ()
Default
(Integer 4 [])
Source
Public),
x:
(Variable
3
x
Local ()
Default
(Integer 4 [])
Source
Public)
})
h [] [
(=
(Var 3 x) (ConstantInteger 1
(Integer 4 [])))
(DoLoop
(
(Var 3 i) (ConstantInteger 1
(Integer 4 [])) (ConstantInteger 10
(Integer 4 [])) ()) [
(=
(Var 3 x)
(BinOp
(Var 3 i)
Mul
(Var 3 x)
(Integer 4 [])))])]
Source
Public)
})
[])
13 changes: 13 additions & 0 deletions tests/reference/ast_indent-subroutine1-3a55d20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "ast_indent-subroutine1-3a55d20",
"cmd": "lfortran --show-ast --indent --no-color {infile} -o {outfile}",
"infile": "tests/subroutine1.f90",
"infile_hash": "e209c22328b423e75d6801f3c0ef19bc120936196435dff2cb19df31",
"outfile": null,
"outfile_hash": null,
"stdout": "ast_indent-subroutine1-3a55d20.stdout",
"stdout_hash": "5785ca26e75959e4e7b9753ac07e3e5f9f2a9e554c03ba3f6dede2f1",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
18 changes: 18 additions & 0 deletions tests/reference/ast_indent-subroutine1-3a55d20.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(TranslationUnit
[
(Subroutine
g [] [] [
(Declaration [
(x "integer" () [] [] [] ())
(i "integer" () [] [] [] ())])] [
(= x 1)
(DoLoop i 1 10 () [
(= x (* x i))])] [])
(Subroutine
h [] [] [
(Declaration [
(x "integer" () [] [] [] ())
(i "integer" () [] [] [] ())])] [
(= x 1)
(DoLoop i 1 10 () [
(= x (* i x))])] [])])
2 changes: 2 additions & 0 deletions tests/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
[[test]]
filename = "subroutine1.f90"
tokens = true
ast_indent = true
asr_indent = true
ast = true

[[test]]
Expand Down

0 comments on commit 67bdb41

Please sign in to comment.