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

     1  package golang
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/nevalang/neva/internal/compiler"
     8  	"github.com/nevalang/neva/internal/runtime/ir"
     9  )
    10  
    11  func getMsg(msg *ir.Msg) (string, error) {
    12  	if msg == nil {
    13  		return "nil", nil
    14  	}
    15  	switch msg.Type {
    16  	case ir.MsgTypeBool:
    17  		return fmt.Sprintf("runtime.NewBoolMsg(%v)", msg.Bool), nil
    18  	case ir.MsgTypeInt:
    19  		return fmt.Sprintf("runtime.NewIntMsg(%v)", msg.Int), nil
    20  	case ir.MsgTypeFloat:
    21  		return fmt.Sprintf("runtime.NewFloatMsg(%v)", msg.Float), nil
    22  	case ir.MsgTypeString:
    23  		return fmt.Sprintf(`runtime.NewStrMsg("%v")`, msg.Str), nil
    24  	case ir.MsgTypeList:
    25  		s := `runtime.NewListMsg(
    26  	`
    27  		for _, v := range msg.List {
    28  			el, err := getMsg(compiler.Pointer(v))
    29  			if err != nil {
    30  				return "", err
    31  			}
    32  			s += fmt.Sprintf(`	%v,
    33  `, el)
    34  		}
    35  		return s + ")", nil
    36  	case ir.MsgTypeMap:
    37  		s := `runtime.NewMapMsg(map[string]runtime.Msg{
    38  	`
    39  		for k, v := range msg.Map {
    40  			el, err := getMsg(compiler.Pointer(v))
    41  			if err != nil {
    42  				return "", err
    43  			}
    44  			s += fmt.Sprintf(`	"%v": %v,
    45  `, k, el)
    46  		}
    47  		return s + `},
    48  )`, nil
    49  	}
    50  
    51  	return "", fmt.Errorf("%w: %v", ErrUnknownMsgType, msg.Type)
    52  }
    53  
    54  func getConnComment(conn *ir.Connection) string {
    55  	s := fmtPortAddr(conn.SenderSide) + " -> "
    56  	for _, rcvr := range conn.ReceiverSides {
    57  		s += fmtPortAddr(rcvr.PortAddr)
    58  	}
    59  	return "// " + s
    60  }
    61  
    62  func fmtPortAddr(addr ir.PortAddr) string {
    63  	return fmt.Sprintf("%s:%s[%d]", addr.Path, addr.Port, addr.Idx)
    64  }
    65  
    66  func getPortChanName(addr *ir.PortAddr) string {
    67  	path := handleSpecialChars(addr.Path)
    68  	port := addr.Port
    69  	result := fmt.Sprintf("%s_%s_%d_port", path, port, addr.Idx)
    70  	return result
    71  }
    72  
    73  func getFuncIOPorts(addrs []ir.PortAddr) string {
    74  	m := map[string][]string{}
    75  	for _, addr := range addrs {
    76  		m[addr.Port] = append(
    77  			m[addr.Port],
    78  			getPortChanName(compiler.Pointer(addr)),
    79  		)
    80  	}
    81  
    82  	s := ""
    83  	for port, chans := range m {
    84  		s += fmt.Sprintf(`"%s": {`, port)
    85  		for _, ch := range chans {
    86  			s += ch + ","
    87  		}
    88  		s += "},\n"
    89  	}
    90  
    91  	return s
    92  }
    93  
    94  func handleSpecialChars(portPath string) string {
    95  	var buffer bytes.Buffer
    96  	for _, r := range portPath {
    97  		switch r {
    98  		case '$', '.', '/', ':':
    99  			buffer.WriteRune('_')
   100  		default:
   101  			buffer.WriteRune(r)
   102  		}
   103  	}
   104  	return buffer.String()
   105  }