-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathnode.v
More file actions
193 lines (159 loc) · 5.12 KB
/
Copy pathnode.v
File metadata and controls
193 lines (159 loc) · 5.12 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// To generate example AST JSON, that Node structure maps,
// use clang -w -Xclang -ast-dump=json -fsyntax-only -fno-diagnostics-color -c 1.hello.c > ast.json command, for example.
module main
type Value = string | int | bool
// vfmt off
struct Node {
id string
kind_str string @[json: 'kind'] // e.g. "IntegerLiteral"
previous_declaration string @[json: 'previousDecl']
name string // e.g. "my_var_name"
ast_type AstJsonType @[json: 'type']
class_modifier string @[json: 'storageClass']
tags string @[json: 'tagUsed']
initialization_type string @[json: 'init'] // "c" => "cinit"
value Value @[json: 'value'] // For CharacterLiterals, since `value` is a number there, not at string
opcode string // e.g. "+" in BinaryOperator
mangled_name string @[json: 'mangledName'] // C++ mangled name for methods
cast_kind string @[json: 'castKind'] // e.g. "BitCast" in ImplicitCastExpr
ast_argument_type AstJsonType @[json: 'argType']
bases []CxxBaseSpecifier @[json: 'bases']
declaration_id string @[json: 'declId'] // for goto labels
label_id string @[json: 'targetLabelDeclId'] // for goto statements
is_postfix bool @[json: 'isPostfix']
mut:
//parent_node &Node [skip] = unsafe {nil }
location NodeLocation @[json: 'loc']
comment string @[skip] // comment string before this node
unique_id int = -1 @[skip]
range Range
inner []Node
array_filler []Node // for InitListExpr
ref_declaration RefDeclarationNode @[json: 'referencedDecl'] //&Node
kind NodeKind @[skip]
current_child_id int @[skip]
redeclarations_count int @[skip] // increased when some *other* Node had previous_decl == this Node.id
owned_tag_decl OwnedTagDecl @[json: 'ownedTagDecl'] // for TagDecl nodes, to store the TagDecl node that is owned by this node
}
// vfmt on
struct NodeLocation {
mut:
offset int
file string @[json: 'file']
line int
source_file SourceFile @[json: 'includedFrom']
spelling_file SourceFile @[json: 'spellingLoc']
file_index int = -1
}
struct Range {
mut:
begin Begin
end End
}
struct Begin {
mut:
offset int
file string @[json: 'file']
spelling_file SourceFile @[json: 'spellingLoc']
expansion_file SourceFile @[json: 'expansionLoc']
}
struct End {
mut:
offset int
file string @[json: 'file']
spelling_file SourceFile @[json: 'spellingLoc']
expansion_file SourceFile @[json: 'expansionLoc']
}
struct SourceFile {
offset int @[json: 'offset']
path string @[json: 'file']
}
struct AstJsonType {
desugared_qualified string @[json: 'desugaredQualType']
qualified string @[json: 'qualType']
}
struct CxxBaseSpecifier {
access string
written_access string @[json: 'writtenAccess']
ast_type AstJsonType @[json: 'type']
}
struct RefDeclarationNode {
kind_str string @[json: 'kind'] // e.g. "IntegerLiteral"
name string
mut:
kind NodeKind @[skip]
}
struct OwnedTagDecl {
id string
kind_str string @[json: 'kind']
name string
}
const bad_node = Node{
kind: .bad
}
fn (value Value) to_str() string {
if value is int {
return value.str()
} else if value is bool {
return if value { 'true' } else { 'false' }
} else {
return value as string
}
}
fn (node Node) kindof(expected_kind NodeKind) bool {
return node.kind == expected_kind
}
fn (node Node) has_child_of_kind(expected_kind NodeKind) bool {
for child in node.inner {
if child.kindof(expected_kind) {
return true
}
}
return false
}
fn (node Node) count_children_of_kind(kind_filter NodeKind) int {
mut count := 0
for child in node.inner {
if child.kindof(kind_filter) {
count++
}
}
return count
}
fn (node Node) find_children(wanted_kind NodeKind) []Node {
mut suitable_children := []Node{}
if node.inner.len == 0 {
return suitable_children
}
for child in node.inner {
if child.kindof(wanted_kind) {
suitable_children << child
}
}
return suitable_children
}
fn (mut node Node) try_get_next_child_of_kind(wanted_kind NodeKind) !Node {
if node.current_child_id >= node.inner.len {
return error('No more children')
}
mut current_child := node.inner[node.current_child_id]
if current_child.kindof(wanted_kind) == false {
error('try_get_next_child_of_kind(): WANTED ${wanted_kind.str()} BUT GOT ${current_child.kind.str()}')
}
node.current_child_id++
return current_child
}
fn (mut node Node) try_get_next_child() !Node {
if node.current_child_id >= node.inner.len {
return error('No more children')
}
current_child := node.inner[node.current_child_id]
node.current_child_id++
return current_child
}
fn (mut node Node) initialize_node_and_children() {
node.kind = convert_str_into_node_kind(node.kind_str)
for mut child in node.inner {
child.initialize_node_and_children()
}
}