Skip to content

Commit a08810b

Browse files
committed
Ast dump Comprehension structs properly
1 parent 69f12ff commit a08810b

File tree

2 files changed

+45
-34
lines changed

2 files changed

+45
-34
lines changed

ast/dump.go

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,59 +8,67 @@ import (
88
"github.com/ncw/gpython/py"
99
)
1010

11-
// Dump an Ast node as a string
12-
func Dump(ast Ast) string {
13-
if ast == nil {
14-
return "<nil>"
15-
}
16-
name := ast.Type().Name
17-
if name == "ExprStmt" {
18-
name = "Expr"
11+
func dumpItem(v interface{}) string {
12+
switch x := v.(type) {
13+
case py.String:
14+
return fmt.Sprintf("'%s'", string(x))
15+
case py.Bytes:
16+
return fmt.Sprintf("b'%s'", string(x))
17+
case Identifier:
18+
return fmt.Sprintf("'%s'", string(x))
19+
case ModBase:
20+
case StmtBase:
21+
case ExprBase:
22+
case SliceBase:
23+
case Pos:
24+
case Ast:
25+
return Dump(x)
26+
case py.I__str__:
27+
return string(x.M__str__().(py.String))
28+
case Comprehension:
29+
return dump(v, "comprehension")
1930
}
31+
return fmt.Sprintf("%v", v)
32+
}
33+
34+
// Dump ast as a string with name
35+
func dump(ast interface{}, name string) string {
2036
astValue := reflect.Indirect(reflect.ValueOf(ast))
2137
astType := astValue.Type()
2238
args := make([]string, 0)
2339
for i := 0; i < astType.NumField(); i++ {
2440
fieldType := astType.Field(i)
2541
fieldValue := astValue.Field(i)
2642
fname := strings.ToLower(fieldType.Name)
43+
if fname == "stmtbase" || fname == "exprbase" || fname == "modbase" {
44+
continue
45+
}
2746
if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() != reflect.Uint8 {
2847
strs := make([]string, fieldValue.Len())
2948
for i := 0; i < fieldValue.Len(); i++ {
3049
element := fieldValue.Index(i)
3150
if element.CanInterface() {
32-
if x, ok := element.Interface().(Ast); ok {
33-
strs[i] = Dump(x)
34-
} else {
35-
strs[i] = fmt.Sprintf("%v", element)
36-
}
37-
} else {
38-
strs[i] = fmt.Sprintf("%v", element)
51+
v := element.Interface()
52+
strs[i] = dumpItem(v)
3953
}
4054
}
4155
args = append(args, fmt.Sprintf("%s=[%s]", fname, strings.Join(strs, ", ")))
4256
} else if fieldValue.CanInterface() {
4357
v := fieldValue.Interface()
44-
switch x := v.(type) {
45-
case py.String:
46-
args = append(args, fmt.Sprintf("%s='%s'", fname, string(x)))
47-
case py.Bytes:
48-
args = append(args, fmt.Sprintf("%s=b'%s'", fname, string(x)))
49-
case Identifier:
50-
args = append(args, fmt.Sprintf("%s='%s'", fname, string(x)))
51-
case ModBase:
52-
case StmtBase:
53-
case ExprBase:
54-
case SliceBase:
55-
case Pos:
56-
case Ast:
57-
args = append(args, fmt.Sprintf("%s=%s", fname, Dump(x)))
58-
case py.I__str__:
59-
args = append(args, fmt.Sprintf("%s=%s", fname, x.M__str__()))
60-
default:
61-
args = append(args, fmt.Sprintf("%s=%v", fname, x))
62-
}
58+
args = append(args, fmt.Sprintf("%s=%s", fname, dumpItem(v)))
6359
}
6460
}
6561
return fmt.Sprintf("%s(%s)", name, strings.Join(args, ", "))
6662
}
63+
64+
// Dump an Ast node as a string
65+
func Dump(ast Ast) string {
66+
if ast == nil {
67+
return "<nil>"
68+
}
69+
name := ast.Type().Name
70+
if name == "ExprStmt" {
71+
name = "Expr"
72+
}
73+
return dump(ast, name)
74+
}

ast/dump_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ func TestDump(t *testing.T) {
2323
{&Module{Body: []Stmt{&ExprStmt{Value: &Tuple{}}}}, `Module(body=[Expr(value=Tuple(elts=[], ctx=UnknownExprContext(0)))])`},
2424
{&NameConstant{Value: py.True}, `NameConstant(value=True)`},
2525
{&Name{Id: Identifier("hello"), Ctx: Load}, `Name(id='hello', ctx=Load())`},
26+
{&ListComp{Elt: &Str{S: py.String("potato")}, Generators: []Comprehension{{
27+
Target: &Name{Id: Identifier("hello"), Ctx: Load},
28+
}}}, `ListComp(elt=Str(s='potato'), generators=[comprehension(target=Name(id='hello', ctx=Load()), iter=<nil>, ifs=[])])`},
2629
} {
2730
out := Dump(test.in)
2831
if out != test.out {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy