github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/backend/golang/backend.go (about)

     1  package golang
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io/fs"
     7  	"text/template"
     8  
     9  	"github.com/nevalang/neva/internal"
    10  	"github.com/nevalang/neva/internal/compiler"
    11  	"github.com/nevalang/neva/internal/runtime/ir"
    12  )
    13  
    14  type Backend struct{}
    15  
    16  var (
    17  	ErrExecTmpl       = errors.New("execute template")
    18  	ErrWrongGoVersion = errors.New("wrong Go version")
    19  	ErrUnknownMsgType = errors.New("unknown msg type")
    20  )
    21  
    22  func (b Backend) Emit(dst string, prog *ir.Program) error {
    23  	tmpl, err := template.New("tpl.go").Funcs(template.FuncMap{
    24  		"getMsg":          getMsg,
    25  		"getFuncIOPorts":  getFuncIOPorts,
    26  		"getPortChanName": getPortChanName,
    27  		"getConnComment":  getConnComment,
    28  	}).Parse(mainGoTemplate)
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	var buf bytes.Buffer
    34  	if err := tmpl.Execute(&buf, prog); err != nil {
    35  		return errors.Join(ErrExecTmpl, err)
    36  	}
    37  
    38  	result := map[string][]byte{}
    39  	result["main.go"] = buf.Bytes()
    40  	result["go.mod"] = []byte("module github.com/nevalang/neva/internal\n\ngo 1.21") //nolint:lll // must match imports in runtime package
    41  
    42  	if err := putRuntime(result); err != nil {
    43  		return err
    44  	}
    45  
    46  	return compiler.SaveFilesToDir(dst, result)
    47  }
    48  
    49  func putRuntime(files map[string][]byte) error {
    50  	if err := fs.WalkDir(
    51  		internal.Efs,
    52  		"runtime",
    53  		func(path string, dirEntry fs.DirEntry, err error) error {
    54  			if err != nil {
    55  				return err
    56  			}
    57  
    58  			if dirEntry.IsDir() {
    59  				return nil
    60  			}
    61  
    62  			bb, err := internal.Efs.ReadFile(path)
    63  			if err != nil {
    64  				return err
    65  			}
    66  
    67  			files[path] = bb
    68  			return nil
    69  		},
    70  	); err != nil {
    71  		return err
    72  	}
    73  
    74  	return nil
    75  }
    76  
    77  func NewBackend() Backend {
    78  	return Backend{}
    79  }