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