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