-
Notifications
You must be signed in to change notification settings - Fork 9
/
parse_const.go
101 lines (96 loc) · 2.35 KB
/
parse_const.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
95
96
97
98
99
100
101
package main
import (
"go/ast"
"go/token"
"log"
"strconv"
"strings"
)
func ParseGenDeclConst(decl *ast.GenDecl, objectTypeMap *ObjectTypeMap) []string {
var ret []string
iotaStart := 0
incFlag := false
shiftFlag := false
for sIdx, spec := range decl.Specs {
if vs, ok := spec.(*ast.ValueSpec); ok {
var names []string
for _, name := range vs.Names {
names = append(names, name.Name)
}
var values []string
for vIdx, value := range vs.Values {
if v, ok := value.(*ast.BasicLit); ok {
switch v.Kind {
case token.STRING:
values = append(values, v.Value)
break
case token.INT:
values = append(values, v.Value)
break
case token.FLOAT:
values = append(values, v.Value)
break
case token.CHAR:
values = append(values, v.Value)
break
default:
log.Fatal("invalid basicLit type")
}
} else {
val := ParseExpr(value)
if strings.Contains(val, "iota") {
if vIdx != 0 {
log.Fatal("only one value when encounter iota")
}
if val == "iota" {
iotaStart = 0
incFlag = true
shiftFlag = false
values = append(values, "0")
} else if strings.Contains(val, "1<<iota") {
iotaStart = 0
incFlag = false
shiftFlag = true
values = append(values, "1ul")
} else if strings.Contains(val, "iota+1") {
iotaStart = 1
incFlag = false
shiftFlag = true
values = append(values, "1ul")
} else {
log.Fatal("unknown value : " + val)
}
} else {
values = append(values, val)
}
}
}
if sIdx > 0 && len(vs.Values) == 0 {
if incFlag {
iotaStart++
values = append(values, strconv.Itoa(iotaStart))
} else if shiftFlag {
iotaStart++
values = append(values, "(1ul << " + strconv.Itoa(iotaStart) + ")")
}
}
if len(names) != len(values) {
if len(values) == 1 {
for _, name := range names {
ret = append(ret, "#define " + name + " " + values[0])
}
} else {
log.Print("invalid names size and values size")
log.Print("names: " + strings.Join(names, " "))
log.Print("values: " + strings.Join(values, " "))
log.Fatal("invalid sizes")
}
} else {
for i, name := range names {
ret = append(ret, "#define " + name + " " + values[i])
}
}
}
}
return ret
}