exports.mx raw
1 package main
2
3 import (
4 "bytes"
5 "unsafe"
6 )
7
8 var fileHandles []*File
9
10 func allocFileHandle(f *File) int32 {
11 for i, h := range fileHandles {
12 if h == nil {
13 fileHandles[i] = f
14 return int32(i)
15 }
16 }
17 fileHandles = append(fileHandles, f)
18 return int32(len(fileHandles) - 1)
19 }
20
21 func getFile(h int32) *File {
22 if h < 0 || int(h) >= len(fileHandles) {
23 return nil
24 }
25 return fileHandles[h]
26 }
27
28 func copyOut(dst unsafe.Pointer, cap int32, src string) int32 {
29 n := int32(len(src))
30 if n > cap {
31 n = cap
32 }
33 if n > 0 {
34 buf := unsafe.Slice((*byte)(dst), n)
35 copy(buf, src[:n])
36 }
37 return n
38 }
39
40 //export moxie_parse_file
41 func moxie_parse_file(pathPtr unsafe.Pointer, pathLen int32) int32 {
42 path := string(unsafe.Slice((*byte)(pathPtr), pathLen))
43 f, err := ParseFile(path, nil, nil, 0)
44 if err != nil || f == nil {
45 return -1
46 }
47 return allocFileHandle(f)
48 }
49
50 //export moxie_parse_bytes
51 func moxie_parse_bytes(srcPtr unsafe.Pointer, srcLen int32, namePtr unsafe.Pointer, nameLen int32) int32 {
52 src := unsafe.Slice((*byte)(srcPtr), srcLen)
53 name := string(unsafe.Slice((*byte)(namePtr), nameLen))
54 r := bytes.NewReader(src)
55 f, err := Parse(NewFileBase(name), r, nil, nil, 0)
56 if err != nil || f == nil {
57 return -1
58 }
59 return allocFileHandle(f)
60 }
61
62 //export moxie_file_pkg_name
63 func moxie_file_pkg_name(h int32, out unsafe.Pointer, cap int32) int32 {
64 f := getFile(h)
65 if f == nil || f.PkgName == nil {
66 return 0
67 }
68 return copyOut(out, cap, f.PkgName.Value)
69 }
70
71 //export moxie_file_decl_count
72 func moxie_file_decl_count(h int32) int32 {
73 f := getFile(h)
74 if f == nil {
75 return 0
76 }
77 return int32(len(f.DeclList))
78 }
79
80 //export moxie_file_decl_kind
81 func moxie_file_decl_kind(h int32, idx int32) int32 {
82 f := getFile(h)
83 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
84 return 0
85 }
86 switch f.DeclList[idx].(type) {
87 case *ImportDecl:
88 return 1
89 case *ConstDecl:
90 return 2
91 case *TypeDecl:
92 return 3
93 case *VarDecl:
94 return 4
95 case *FuncDecl:
96 return 5
97 }
98 return 0
99 }
100
101 //export moxie_file_import_path
102 func moxie_file_import_path(h int32, idx int32, out unsafe.Pointer, cap int32) int32 {
103 f := getFile(h)
104 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
105 return 0
106 }
107 d, ok := f.DeclList[idx].(*ImportDecl)
108 if !ok || d.Path == nil {
109 return 0
110 }
111 return copyOut(out, cap, d.Path.Value)
112 }
113
114 //export moxie_file_func_name
115 func moxie_file_func_name(h int32, idx int32, out unsafe.Pointer, cap int32) int32 {
116 f := getFile(h)
117 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
118 return 0
119 }
120 d, ok := f.DeclList[idx].(*FuncDecl)
121 if !ok || d.Name == nil {
122 return 0
123 }
124 return copyOut(out, cap, d.Name.Value)
125 }
126
127 //export moxie_file_func_has_body
128 func moxie_file_func_has_body(h int32, idx int32) int32 {
129 f := getFile(h)
130 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
131 return 0
132 }
133 d, ok := f.DeclList[idx].(*FuncDecl)
134 if !ok {
135 return 0
136 }
137 if d.Body != nil {
138 return 1
139 }
140 return 0
141 }
142
143 //export moxie_file_func_param_count
144 func moxie_file_func_param_count(h int32, idx int32) int32 {
145 f := getFile(h)
146 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
147 return 0
148 }
149 d, ok := f.DeclList[idx].(*FuncDecl)
150 if !ok || d.Type == nil {
151 return 0
152 }
153 return int32(len(d.Type.ParamList))
154 }
155
156 //export moxie_file_func_result_count
157 func moxie_file_func_result_count(h int32, idx int32) int32 {
158 f := getFile(h)
159 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
160 return 0
161 }
162 d, ok := f.DeclList[idx].(*FuncDecl)
163 if !ok || d.Type == nil {
164 return 0
165 }
166 return int32(len(d.Type.ResultList))
167 }
168
169 //export moxie_file_func_body_stmt_count
170 func moxie_file_func_body_stmt_count(h int32, idx int32) int32 {
171 f := getFile(h)
172 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
173 return 0
174 }
175 d, ok := f.DeclList[idx].(*FuncDecl)
176 if !ok || d.Body == nil {
177 return 0
178 }
179 return int32(len(d.Body.List))
180 }
181
182 //export moxie_file_func_has_recv
183 func moxie_file_func_has_recv(h int32, idx int32) int32 {
184 f := getFile(h)
185 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
186 return 0
187 }
188 d, ok := f.DeclList[idx].(*FuncDecl)
189 if !ok {
190 return 0
191 }
192 if d.Recv != nil {
193 return 1
194 }
195 return 0
196 }
197
198 //export moxie_file_type_name
199 func moxie_file_type_name(h int32, idx int32, out unsafe.Pointer, cap int32) int32 {
200 f := getFile(h)
201 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
202 return 0
203 }
204 d, ok := f.DeclList[idx].(*TypeDecl)
205 if !ok || d.Name == nil {
206 return 0
207 }
208 return copyOut(out, cap, d.Name.Value)
209 }
210
211 //export moxie_file_type_is_alias
212 func moxie_file_type_is_alias(h int32, idx int32) int32 {
213 f := getFile(h)
214 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
215 return 0
216 }
217 d, ok := f.DeclList[idx].(*TypeDecl)
218 if !ok {
219 return 0
220 }
221 if d.Alias {
222 return 1
223 }
224 return 0
225 }
226
227 //export moxie_file_var_name_count
228 func moxie_file_var_name_count(h int32, idx int32) int32 {
229 f := getFile(h)
230 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
231 return 0
232 }
233 d, ok := f.DeclList[idx].(*VarDecl)
234 if !ok {
235 return 0
236 }
237 return int32(len(d.NameList))
238 }
239
240 //export moxie_file_const_name_count
241 func moxie_file_const_name_count(h int32, idx int32) int32 {
242 f := getFile(h)
243 if f == nil || idx < 0 || int(idx) >= len(f.DeclList) {
244 return 0
245 }
246 d, ok := f.DeclList[idx].(*ConstDecl)
247 if !ok {
248 return 0
249 }
250 return int32(len(d.NameList))
251 }
252
253 //export moxie_file_go_version
254 func moxie_file_go_version(h int32, out unsafe.Pointer, cap int32) int32 {
255 f := getFile(h)
256 if f == nil {
257 return 0
258 }
259 return copyOut(out, cap, f.GoVersion)
260 }
261
262 //export moxie_file_free
263 func moxie_file_free(h int32) {
264 if h >= 0 && int(h) < len(fileHandles) {
265 fileHandles[h] = nil
266 }
267 }
268
269 func main() {}
270