main.mx raw
1 package main
2
3 import "unsafe"
4
5 //export write
6 func cWrite(fd int32, buf unsafe.Pointer, count uint32) (n int32)
7
8 //export mxc_readfile
9 func cReadfile(path unsafe.Pointer, pathLen int32, buf unsafe.Pointer, bufCap int32) (n int32)
10
11 //export mxc_filesize
12 func cFilesize(path unsafe.Pointer, pathLen int32) (n int32)
13
14 var nl = []byte{10}
15
16 func out(s string) {
17 if len(s) > 0 {
18 cWrite(1, unsafe.Pointer(&[]byte(s)[0]), uint32(len(s)))
19 }
20 }
21
22 func outln(s string) {
23 out(s)
24 cWrite(1, unsafe.Pointer(&nl[0]), 1)
25 }
26
27 func fatal(s string) {
28 if len(s) > 0 {
29 cWrite(2, unsafe.Pointer(&[]byte(s)[0]), uint32(len(s)))
30 }
31 cWrite(2, unsafe.Pointer(&nl[0]), 1)
32 }
33
34 func readFile(path string) (data []byte, ok bool) {
35 sz := cFilesize(unsafe.Pointer(&[]byte(path)[0]), int32(len(path)))
36 if sz < 0 { return nil, false }
37 buf := []byte{:sz+1}
38 n := cReadfile(unsafe.Pointer(&[]byte(path)[0]), int32(len(path)), unsafe.Pointer(&buf[0]), sz+1)
39 if n < 0 { return nil, false }
40 return buf[:n], true
41 }
42
43 func getArgs() (ss []string) {
44 buf := []byte{:4096}
45 n := cReadfile(unsafe.Pointer(&[]byte("/proc/self/cmdline")[0]), 18, unsafe.Pointer(&buf[0]), 4096)
46 if n <= 0 { return nil }
47 var args []string
48 start := int32(0)
49 for i := int32(0); i < n; i++ {
50 if buf[i] == 0 {
51 if i > start { args = append(args, string(buf[start:i])) }
52 start = i + 1
53 }
54 }
55 return args
56 }
57
58 func main() {
59 args := getArgs()
60 if len(args) < 2 { fatal("usage: mxparse <file.mx>"); return }
61 path := args[1]
62 data, ok := readFile(path)
63 if !ok { fatal("error: cannot read " | path); return }
64 file := parseSource(path, data)
65 if file == nil { fatal("parse failed"); return }
66 outln("File " | path)
67 if file.PkgName == nil {
68 outln("PkgName: nil")
69 } else {
70 outln("Package " | file.PkgName.Value)
71 }
72 outln("Decls: " | ItoaU32(uint32(len(file.DeclList))))
73 for i := int32(0); i < int32(len(file.DeclList)); i++ {
74 d := file.DeclList[i]
75 if fd, ok := d.(*FuncDecl); ok && fd != nil {
76 r := ""
77 if fd.Recv != nil { r = "(method) " }
78 name := "_"
79 if fd.Name != nil { name = fd.Name.Value }
80 outln("Func " | r | name)
81 } else if td, ok := d.(*TypeDecl); ok && td != nil {
82 outln("Type " | td.Name.Value)
83 } else if _, ok := d.(*VarDecl); ok {
84 outln("Var")
85 } else if _, ok := d.(*ConstDecl); ok {
86 outln("Const")
87 } else if id, ok := d.(*ImportDecl); ok && id != nil {
88 p := ""
89 if id.Path != nil { p = id.Path.Value }
90 outln("Import " | p)
91 } else {
92 outln("Decl?")
93 }
94 }
95 }
96