-
Notifications
You must be signed in to change notification settings - Fork 0
/
expr.go
94 lines (90 loc) · 2.47 KB
/
expr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package go2cpp
import (
"fmt"
"go/ast"
"go/token"
"log"
)
func parseExpr(fullText []byte, expr ast.Expr) (string, error) {
switch v := expr.(type) {
case *ast.BasicLit:
return parseBasicLit(fullText, v)
case *ast.Ident:
return parseIdent(fullText, v)
case *ast.BinaryExpr:
return parseBinaryExpr(fullText, v)
case *ast.CallExpr:
return parseCallExpr(fullText, v)
default:
return "", fmt.Errorf("unsupported expression: %s", stringifyNode(fullText, expr))
}
}
func parseCallExpr(fullText []byte, call *ast.CallExpr) (string, error) {
switch f := call.Fun.(type) {
case *ast.SelectorExpr:
text := stringifyNode(fullText, f)
if text == "errors.New" || text == "fmt.Errorf" {
if len(call.Args) == 0 {
return "", fmt.Errorf("wrong call expr: %s", stringifyNode(fullText, call))
}
expr, e := parseExpr(fullText, call.Args[0])
if e != nil {
log.Println(e)
return "", e
}
return "QString(" + expr + ")", nil
}
return "unsupported", nil
default:
return "", fmt.Errorf("unsupported call expr: %s", stringifyNode(fullText, call))
}
}
func parseBinaryExpr(fullText []byte, binary *ast.BinaryExpr) (string, error) {
switch binary.Op {
case token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, // &
token.OR, // |
token.XOR, // ^
token.SHL, // <<
token.SHR, // >>
token.AND_NOT, // &^
token.ADD_ASSIGN, // +=
token.SUB_ASSIGN, // -=
token.MUL_ASSIGN, // *=
token.QUO_ASSIGN, // /=
token.REM_ASSIGN, // %=
token.AND_ASSIGN, // &=
token.OR_ASSIGN, // |=
token.XOR_ASSIGN, // ^=
token.SHL_ASSIGN, // <<=
token.SHR_ASSIGN, // >>=
token.AND_NOT_ASSIGN, // &^=
token.LAND, // &&
token.LOR, // ||
token.ARROW, // <-
token.INC, // ++
token.DEC, // --
token.EQL, // ==
token.LSS, // <
token.GTR, // >
token.ASSIGN, // =
token.NOT, // !
token.NEQ, // !=
token.LEQ, // <=
token.GEQ, // >=
token.DEFINE: // :=
default:
return "", fmt.Errorf("unsupported binary expr: %s", stringifyNode(fullText, binary))
}
left, e := parseExpr(fullText, binary.X)
if e != nil {
log.Println(e)
return "", e
}
right, e := parseExpr(fullText, binary.Y)
if e != nil {
log.Println(e)
return "", e
}
return left + " " + binary.Op.String() + " " + right, nil
}