syntax.mx raw

   1  package syntax
   2  
   3  import (
   4  	"io"
   5  	"os"
   6  	"runtime"
   7  	"git.smesh.lol/moxie/pkg/token"
   8  )
   9  
  10  type Mode uint32
  11  
  12  const (
  13  	CheckBranches Mode = 1 << iota
  14  )
  15  
  16  type Error struct {
  17  	Pos token.Pos
  18  	Msg string
  19  }
  20  
  21  func (err *Error) Error() (s string) {
  22  	return err.Pos.String() | ": " | err.Msg
  23  }
  24  
  25  func (err *Error) String() (s string) { return err.Error() }
  26  
  27  var CompileExportMap map[string]string
  28  
  29  type ErrorHandler func(err error)
  30  
  31  type Pragma interface{}
  32  
  33  type PragmaHandler func(pos token.Pos, blank bool, text string, current Pragma) Pragma
  34  
  35  func Parse(base *token.PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) {
  36  	defer func() {
  37  		if rv := recover(); rv != nil {
  38  			if err, ok := rv.(*Error); ok {
  39  				first = err
  40  				return
  41  			}
  42  			panic(rv)
  43  		}
  44  	}()
  45  
  46  	var p Parser
  47  	p.init(base, src, errh, pragh, mode)
  48  	p.Next()
  49  	return p.fileOrNil(), p.First
  50  }
  51  
  52  func ParseBytes(base *token.PosBase, src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) {
  53  	return ParseBytesArena(base, src, errh, pragh, mode, nil)
  54  }
  55  
  56  func ParseBytesArena(base *token.PosBase, src []byte, errh ErrorHandler, pragh PragmaHandler, mode Mode, arena *runtime.Arena) (_ *File, first error) {
  57  	var p Parser
  58  	p.Arena = arena
  59  	p.initBytes(base, src, errh, pragh, mode)
  60  	return parseWithRecover(&p)
  61  }
  62  
  63  func parseWithRecover(p *Parser) (_ *File, first error) {
  64  	defer func() {
  65  		if rv := recover(); rv != nil {
  66  			if err, ok := rv.(*Error); ok {
  67  				first = err
  68  				return
  69  			}
  70  			panic(rv)
  71  		}
  72  	}()
  73  
  74  	p.Next()
  75  	return p.fileOrNil(), p.First
  76  }
  77  
  78  func ParseFile(filename string, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, err error) {
  79  	f, err := os.Open(filename)
  80  	if err != nil {
  81  		if errh != nil {
  82  			errh(err)
  83  		}
  84  		return nil, err
  85  	}
  86  	defer f.Close()
  87  	return Parse(token.NewFileBase(filename), f, errh, pragh, mode)
  88  }
  89